From a9268a7d25350668fa53424c51d8d2069ce0adc5 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 21 May 2019 21:41:30 -0700 Subject: [PATCH 001/364] wip: tree indent guides --- src/vs/base/browser/ui/tree/abstractTree.ts | 124 ++++++++++++++++++-- src/vs/base/browser/ui/tree/media/tree.css | 6 + 2 files changed, 120 insertions(+), 10 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 19feab47a0589..6bc85c35a4378 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -188,6 +188,7 @@ export class ComposedTreeDelegate implements IListV interface ITreeListTemplateData { readonly container: HTMLElement; + readonly indent: HTMLElement; readonly twistie: HTMLElement; readonly templateData: T; } @@ -196,13 +197,47 @@ interface ITreeRendererOptions { readonly indent?: number; } +enum IndentGuide { + None, + First, + Middle, + Last +} + +function getLastVisibleChild(node: ITreeNode): ITreeNode | undefined { + for (let i = 0; i < node.children.length; i++) { + const child = node.children[node.children.length - i - 1]; + + if (child.visible) { + return child; + } + } + + return undefined; +} + +function hasVisibleChildren(node: ITreeNode): boolean { + for (let i = 0; i < node.children.length; i++) { + if (node.children[i].visible) { + return true; + } + } + + return false; +} + +interface IRenderData { + templateData: ITreeListTemplateData; + height: number; +} + class TreeRenderer implements IListRenderer, ITreeListTemplateData> { private static DefaultIndent = 8; readonly templateId: string; private renderedElements = new Map>(); - private renderedNodes = new Map, ITreeListTemplateData>(); + private renderedNodes = new Map, IRenderData>(); private indent: number = TreeRenderer.DefaultIndent; private disposables: IDisposable[] = []; @@ -226,29 +261,38 @@ class TreeRenderer implements IListRenderer { - templateData.twistie.style.marginLeft = `${node.depth * this.indent}px`; + // TODO + this.renderedNodes.forEach((data, node) => { + data.templateData.indent.style.width = `${node.depth * this.indent}px`; }); } renderTemplate(container: HTMLElement): ITreeListTemplateData { const el = append(container, $('.monaco-tl-row')); + const indent = append(el, $('.monaco-tl-indent')); const twistie = append(el, $('.monaco-tl-twistie')); const contents = append(el, $('.monaco-tl-contents')); const templateData = this.renderer.renderTemplate(contents); - return { container, twistie, templateData }; + return { container, indent, twistie, templateData }; } renderElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData, height: number | undefined): void { if (typeof height === 'number') { - this.renderedNodes.set(node, templateData); + this.renderedNodes.set(node, { templateData, height }); this.renderedElements.set(node.element, node); } const indent = TreeRenderer.DefaultIndent + (node.depth - 1) * this.indent; templateData.twistie.style.marginLeft = `${indent}px`; - this.update(node, templateData); + templateData.indent.style.width = `${indent + this.indent}px`; + templateData.indent.style.left = `${Math.floor(this.indent * 1.5)}px`; + + this.renderTwistie(node, templateData); + + if (typeof height === 'number') { + this.renderIndentGuides(node, templateData, height); + } this.renderer.renderElement(node, index, templateData.templateData, height); } @@ -279,16 +323,17 @@ class TreeRenderer implements IListRenderer): void { - const templateData = this.renderedNodes.get(node); + const data = this.renderedNodes.get(node); - if (!templateData) { + if (!data) { return; } - this.update(node, templateData); + this.renderTwistie(node, data.templateData); + this.renderIndentGuides(node, data.templateData, data.height); } - private update(node: ITreeNode, templateData: ITreeListTemplateData) { + private renderTwistie(node: ITreeNode, templateData: ITreeListTemplateData) { if (this.renderer.renderTwistie) { this.renderer.renderTwistie(node.element, templateData.twistie); } @@ -303,6 +348,65 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { + let node: ITreeNode | undefined = _node; + let parent: ITreeNode | undefined; + const guides: IndentGuide[] = []; + + if (node && node.collapsible && !node.collapsed && hasVisibleChildren(node)) { + guides.push(IndentGuide.First); + } else { + guides.push(IndentGuide.None); + } + + while (node) { + parent = node.parent; + + if (!parent || !parent.parent) { + break; + } + + const isLastChild = parent && getLastVisibleChild(parent) === node; + + if (isLastChild) { + if (node === _node) { + guides.push(IndentGuide.Last); + } else { + guides.push(IndentGuide.None); + } + } else { + guides.push(IndentGuide.Middle); + } + + node = parent; + } + + const lines: string[] = []; + const halfHeight = Math.floor(height / 2); + + for (let i = 0; i < guides.length; i++) { + const halfX = Math.floor((guides.length - i - 0.5) * this.indent); + const fullX = (guides.length - i) * this.indent; + + switch (guides[i]) { + case IndentGuide.First: + lines.push(``); + lines.push(``); + break; + case IndentGuide.Middle: + lines.push(``); + break; + case IndentGuide.Last: + lines.push(``); + lines.push(``); + break; + } + } + + const rawSvg = `${lines.join('')}`; + templateData.indent.style.background = `url("data:image/svg+xml,${encodeURIComponent(rawSvg)}") no-repeat 0 0`; + } + dispose(): void { this.renderedNodes.clear(); this.renderedElements.clear(); diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 4f86f971f97c5..059f7ae0e028b 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -9,6 +9,12 @@ align-items: center; } +.monaco-tl-indent { + height: 100%; + position: absolute; + top: 0; +} + .monaco-tl-twistie, .monaco-tl-contents { height: 100%; From 2ec93640df0a12c60ec3b04439e7b319b4982c5c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 22 May 2019 13:57:20 +0200 Subject: [PATCH 002/364] tree indent: dynamic indent --- src/vs/base/browser/ui/tree/abstractTree.ts | 15 +++++++-------- src/vs/base/browser/ui/tree/media/tree.css | 1 + 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 6bc85c35a4378..834bc499c2b63 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -286,7 +286,6 @@ class TreeRenderer implements IListRenderer implements IListRenderer`); - lines.push(``); + lines.push(``); + lines.push(``); break; case IndentGuide.Middle: - lines.push(``); + lines.push(``); break; case IndentGuide.Last: - lines.push(``); - lines.push(``); + lines.push(``); + lines.push(``); break; } } diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 059f7ae0e028b..a0592211ef29f 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -13,6 +13,7 @@ height: 100%; position: absolute; top: 0; + left: 16px; } .monaco-tl-twistie, From 2a0d966fb2face8d119d9b1ec59d6b79d8fdde21 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 22 May 2019 14:04:54 +0200 Subject: [PATCH 003/364] tree indent guides: fix missing first indent guide on async trees --- src/vs/base/browser/ui/tree/abstractTree.ts | 9 ++++++++- src/vs/base/browser/ui/tree/indexTreeModel.ts | 2 +- src/vs/base/browser/ui/tree/tree.ts | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 834bc499c2b63..bbfc2132f9987 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -243,6 +243,7 @@ class TreeRenderer implements IListRenderer, + onDidSplice: Event>, onDidChangeCollapseState: Event>, options: ITreeRendererOptions = {} ) { @@ -251,6 +252,9 @@ class TreeRenderer implements IListRenderer e.node)(this.onDidChangeNodeTwistieState, this, this.disposables); + // TODO: only do iff indent guides are enabled + Event.map(onDidSplice, e => e.parentNode)(this.onDidChangeNodeTwistieState, this, this.disposables); + if (renderer.onDidChangeTwistieState) { renderer.onDidChangeTwistieState(this.onDidChangeTwistieState, this, this.disposables); } @@ -347,6 +351,7 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { let node: ITreeNode | undefined = _node; let parent: ITreeNode | undefined; @@ -1147,8 +1152,9 @@ export abstract class AbstractTree implements IDisposable ) { const treeDelegate = new ComposedTreeDelegate>(delegate); + const onDidSplice = new Relay>(); const onDidChangeCollapseStateRelay = new Relay>(); - this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, _options)); + this.renderers = renderers.map(r => new TreeRenderer(r, onDidSplice.event, onDidChangeCollapseStateRelay.event, _options)); this.disposables.push(...this.renderers); let filter: TypeFilter | undefined; @@ -1164,6 +1170,7 @@ export abstract class AbstractTree implements IDisposable this.view = new TreeNodeList(container, treeDelegate, this.renderers, this.focus, this.selection, { ...asListOptions(() => this.model, _options), tree: this }); this.model = this.createModel(this.view, _options); + onDidSplice.input = this.model.onDidSplice; onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState; this.model.onDidSplice(e => { diff --git a/src/vs/base/browser/ui/tree/indexTreeModel.ts b/src/vs/base/browser/ui/tree/indexTreeModel.ts index a568881e7c2ff..33e5e8c31d6bf 100644 --- a/src/vs/base/browser/ui/tree/indexTreeModel.ts +++ b/src/vs/base/browser/ui/tree/indexTreeModel.ts @@ -171,7 +171,7 @@ export class IndexTreeModel, TFilterData = voi } const result = Iterator.map(Iterator.fromArray(deletedNodes), treeNodeToElement); - this._onDidSplice.fire({ insertedNodes: nodesToInsert, deletedNodes }); + this._onDidSplice.fire({ parentNode, insertedNodes: nodesToInsert, deletedNodes }); return result; } diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index cedb6fbd4232e..e19d172031971 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -98,6 +98,7 @@ export interface ICollapseStateChangeEvent { } export interface ITreeModelSpliceEvent { + parentNode: ITreeNode; insertedNodes: ITreeNode[]; deletedNodes: ITreeNode[]; } From b14e8a74572a13214d65196c0b11da8a7c9a2780 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 22 May 2019 14:41:20 +0200 Subject: [PATCH 004/364] tree indent guides: styling --- src/vs/base/browser/ui/list/listWidget.ts | 5 ++- src/vs/base/browser/ui/tree/abstractTree.ts | 33 ++++++++++++++----- src/vs/base/browser/ui/tree/media/tree.css | 4 +++ src/vs/platform/theme/common/colorRegistry.ts | 1 + src/vs/platform/theme/common/styler.ts | 6 ++-- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index b3cc40b3eee45..4c005afeea7b1 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -857,6 +857,7 @@ export interface IListStyles { listFilterWidgetOutline?: Color; listFilterWidgetNoMatchesOutline?: Color; listMatchesShadow?: Color; + treeIndentGuidesStroke?: Color; } const defaultStyles: IListStyles = { @@ -867,7 +868,8 @@ const defaultStyles: IListStyles = { listFocusAndSelectionForeground: Color.fromHex('#FFFFFF'), listInactiveSelectionBackground: Color.fromHex('#3F3F46'), listHoverBackground: Color.fromHex('#2A2D2E'), - listDropBackground: Color.fromHex('#383B3D') + listDropBackground: Color.fromHex('#383B3D'), + treeIndentGuidesStroke: Color.fromHex('#a9a9a9') }; const DefaultOptions = { @@ -1112,6 +1114,7 @@ export class List implements ISpliceable, IDisposable { return Event.map(this._onPin.event, indexes => this.toListEvent({ indexes })); } + get domId(): string { return this.view.domId; } get onDidScroll(): Event { return this.view.onDidScroll; } get onMouseClick(): Event> { return this.view.onMouseClick; } get onMouseDblClick(): Event> { return this.view.onMouseDblClick; } diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index bbfc2132f9987..b9f558f343e14 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -7,7 +7,7 @@ import 'vs/css!./media/tree'; import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IListOptions, List, IListStyles, mightProducePrintableCharacter, MouseController } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list'; -import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass } from 'vs/base/browser/dom'; +import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, createStyleSheet } from 'vs/base/browser/dom'; import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event'; import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -394,21 +394,23 @@ class TreeRenderer implements IListRenderer`); - lines.push(``); + lines.push(``); + lines.push(``); break; case IndentGuide.Middle: - lines.push(``); + lines.push(``); break; case IndentGuide.Last: - lines.push(``); - lines.push(``); + lines.push(``); + lines.push(``); break; } } - const rawSvg = `${lines.join('')}`; - templateData.indent.style.background = `url("data:image/svg+xml,${encodeURIComponent(rawSvg)}") no-repeat 0 0`; + const width = this.indent * guides.length; + const svg = `${lines.join('')}`; + + templateData.indent.innerHTML = svg; } dispose(): void { @@ -1107,6 +1109,7 @@ export abstract class AbstractTree implements IDisposable private eventBufferer = new EventBufferer(); private typeFilterController?: TypeFilterController; private focusNavigationFilter: ((node: ITreeNode) => boolean) | undefined; + private styleElement: HTMLStyleElement; protected disposables: IDisposable[] = []; get onDidScroll(): Event { return this.view.onDidScroll; } @@ -1193,6 +1196,8 @@ export abstract class AbstractTree implements IDisposable this.focusNavigationFilter = node => this.typeFilterController!.shouldAllowFocus(node); this.disposables.push(this.typeFilterController!); } + + this.styleElement = createStyleSheet(this.view.getHTMLElement()); } updateOptions(optionsUpdate: IAbstractTreeOptionsUpdate = {}): void { @@ -1293,6 +1298,18 @@ export abstract class AbstractTree implements IDisposable } style(styles: IListStyles): void { + const suffix = `.${this.view.domId}`; + const content: string[] = []; + + if (styles.treeIndentGuidesStroke) { + content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke}; }`); + } + + const newStyles = content.join('\n'); + if (newStyles !== this.styleElement.innerHTML) { + this.styleElement.innerHTML = newStyles; + } + this.view.style(styles); } diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index a0592211ef29f..d0b202c0b0a9b 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -16,6 +16,10 @@ left: 16px; } +.monaco-tl-indent > svg { + overflow: visible; +} + .monaco-tl-twistie, .monaco-tl-contents { height: 100%; diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 433b4704b66db..218a9a7057a8b 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -238,6 +238,7 @@ export const listWarningForeground = registerColor('list.warningForeground', { d export const listFilterWidgetBackground = registerColor('listFilterWidget.background', { light: '#efc1ad', dark: '#653723', hc: Color.black }, nls.localize('listFilterWidgetBackground', 'Background color of the type filter widget in lists and trees.')); export const listFilterWidgetOutline = registerColor('listFilterWidget.outline', { dark: Color.transparent, light: Color.transparent, hc: '#f38518' }, nls.localize('listFilterWidgetOutline', 'Outline color of the type filter widget in lists and trees.')); export const listFilterWidgetNoMatchesOutline = registerColor('listFilterWidget.noMatchesOutline', { dark: '#BE1100', light: '#BE1100', hc: contrastBorder }, nls.localize('listFilterWidgetNoMatchesOutline', 'Outline color of the type filter widget in lists and trees, when there are no matches.')); +export const treeIndentGuidesStroke = registerColor('tree.indentGuidesStroke', { dark: '#585858', light: '#a9a9a9', hc: '#a9a9a9' }, nls.localize('treeIndentGuidesStroke', "Tree stroke color for the indentation guides.")); export const pickerGroupForeground = registerColor('pickerGroup.foreground', { dark: '#3794FF', light: '#0066BF', hc: Color.white }, nls.localize('pickerGroupForeground', "Quick picker color for grouping labels.")); export const pickerGroupBorder = registerColor('pickerGroup.border', { dark: '#3F3F46', light: '#CCCEDB', hc: Color.white }, nls.localize('pickerGroupBorder', "Quick picker color for grouping borders.")); diff --git a/src/vs/platform/theme/common/styler.ts b/src/vs/platform/theme/common/styler.ts index beb70d395124b..c6ae9c25e9bc5 100644 --- a/src/vs/platform/theme/common/styler.ts +++ b/src/vs/platform/theme/common/styler.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; -import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground } from 'vs/platform/theme/common/colorRegistry'; +import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground, treeIndentGuidesStroke } from 'vs/platform/theme/common/colorRegistry'; import { IDisposable } from 'vs/base/common/lifecycle'; import { Color } from 'vs/base/common/color'; import { mixin } from 'vs/base/common/objects'; @@ -227,6 +227,7 @@ export interface IListStyleOverrides extends IStyleOverrides { listFilterWidgetOutline?: ColorIdentifier; listFilterWidgetNoMatchesOutline?: ColorIdentifier; listMatchesShadow?: ColorIdentifier; + treeIndentGuidesStroke?: ColorIdentifier; } export function attachListStyler(widget: IThemable, themeService: IThemeService, overrides?: IListStyleOverrides): IDisposable { @@ -252,7 +253,8 @@ export const defaultListStyles: IColorMapping = { listFilterWidgetBackground: listFilterWidgetBackground, listFilterWidgetOutline: listFilterWidgetOutline, listFilterWidgetNoMatchesOutline: listFilterWidgetNoMatchesOutline, - listMatchesShadow: widgetShadow + listMatchesShadow: widgetShadow, + treeIndentGuidesStroke }; export interface IButtonStyleOverrides extends IStyleOverrides { From 45c4f5bbbb884da8bfc8ac1fc305ee21612ec132 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 12 Jun 2019 15:37:21 +0200 Subject: [PATCH 005/364] :lipstick: --- src/vs/base/browser/ui/tree/abstractTree.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index b9f558f343e14..0e2c8573e9d94 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -352,17 +352,18 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { - let node: ITreeNode | undefined = _node; + private renderIndentGuides(target: ITreeNode, templateData: ITreeListTemplateData, height: number): void { let parent: ITreeNode | undefined; const guides: IndentGuide[] = []; - if (node && node.collapsible && !node.collapsed && hasVisibleChildren(node)) { + if (target && target.collapsible && !target.collapsed && hasVisibleChildren(target)) { guides.push(IndentGuide.First); } else { guides.push(IndentGuide.None); } + let node: ITreeNode | undefined = target; + while (node) { parent = node.parent; @@ -370,10 +371,8 @@ class TreeRenderer implements IListRenderer Date: Wed, 12 Jun 2019 16:13:33 +0200 Subject: [PATCH 006/364] demo modes --- src/vs/base/browser/ui/tree/abstractTree.ts | 73 ++++++++++++++++----- src/vs/base/browser/ui/tree/media/tree.css | 1 + 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 0e2c8573e9d94..4046352c17fde 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -216,6 +216,22 @@ function getLastVisibleChild(node: ITreeNode): I return undefined; } +function getLastVisibleDescendant(node: ITreeNode): ITreeNode | undefined { + if (node.collapsed) { + return node; + } + + for (let i = 0; i < node.children.length; i++) { + const child = node.children[node.children.length - i - 1]; + + if (child.visible) { + return getLastVisibleDescendant(child); + } + } + + return undefined; +} + function hasVisibleChildren(node: ITreeNode): boolean { for (let i = 0; i < node.children.length; i++) { if (node.children[i].visible) { @@ -231,6 +247,16 @@ interface IRenderData { height: number; } +//********************************************* DEMO ************************* +enum Mode { + Brackets, + SubtreeBrackets, + Editor +} + +const mode: Mode = Mode.Editor; +//********************************************* DEMO ************************* + class TreeRenderer implements IListRenderer, ITreeListTemplateData> { private static DefaultIndent = 8; @@ -264,11 +290,6 @@ class TreeRenderer implements IListRenderer { - data.templateData.indent.style.width = `${node.depth * this.indent}px`; - }); } renderTemplate(container: HTMLElement): ITreeListTemplateData { @@ -289,7 +310,7 @@ class TreeRenderer implements IListRenderer implements IListRenderer implements IListRenderer`); - lines.push(``); + if (mode === Mode.Editor) { + lines.push(``); + } else { + lines.push(``); + lines.push(``); + } break; case IndentGuide.Middle: lines.push(``); diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index d0b202c0b0a9b..1fcd3853819ba 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -14,6 +14,7 @@ position: absolute; top: 0; left: 16px; + pointer-events: none; } .monaco-tl-indent > svg { From b799118b3935e0a9c7d6e58161b6c10fe7c12860 Mon Sep 17 00:00:00 2001 From: Rob DeLine Date: Wed, 12 Jun 2019 12:49:58 -0700 Subject: [PATCH 007/364] fix --- src/vs/workbench/api/browser/mainThreadCodeInsets.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index e0cbafd346350..e0c2afc675daa 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -92,7 +92,8 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { allowSvgs: false, extension: { id: extensionId, location: URI.revive(extensionLocation) } }, { - allowScripts: options.enableScripts + allowScripts: options.enableScripts, + localResourceRoots: options.localResourceRoots ? options.localResourceRoots.map(uri => URI.revive(uri)) : undefined }); const webviewZone = new EditorWebviewZone(editor, range, webview); From fa4f870501f161747fa032dec006b89476a42baf Mon Sep 17 00:00:00 2001 From: Lee Houghton Date: Sat, 15 Jun 2019 00:36:23 +0100 Subject: [PATCH 008/364] Handle multiple users with /tmp/vscode-typescript This fixes an issue where the typescript language server fails to load if multiple users launch VS Code on the same Linux machine. Steps to reproduce: - Log in as user1 - Launch VS Code - Log out - Log in as user2 - Launch VS Code - It tries to write to files in /tmp/vscode-typescript, but that directory is not writeable because it is owned by user1 - You cannot use TypeScript intellisense This fix namespaces the directory with the current uid so that each user will get their own. On Windows, this shouldn't be an issue anyway since each user gets their own temp directory. --- extensions/typescript-language-features/src/utils/electron.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/utils/electron.ts b/extensions/typescript-language-features/src/utils/electron.ts index 3a1ece8f726be..1f542fe07cc66 100644 --- a/extensions/typescript-language-features/src/utils/electron.ts +++ b/extensions/typescript-language-features/src/utils/electron.ts @@ -7,13 +7,14 @@ import * as temp from './temp'; import path = require('path'); import fs = require('fs'); import cp = require('child_process'); +import process = require('process'); const getRootTempDir = (() => { let dir: string | undefined; return () => { if (!dir) { - dir = temp.getTempFile(`vscode-typescript`); + dir = temp.getTempFile(`vscode-typescript${process.getuid ? process.getuid() : ''}`); } if (!fs.existsSync(dir)) { fs.mkdirSync(dir); From fdb7bd5caac58ec975f9d977aa3f4c0a9d195e24 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 16:44:23 +0200 Subject: [PATCH 009/364] sharp svgs --- src/vs/base/browser/ui/tree/abstractTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index d50166ad7d735..8a4f178c3017f 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -446,7 +446,7 @@ class TreeRenderer implements IListRenderer${lines.join('')}`; + const svg = `${lines.join('')}`; templateData.indent.innerHTML = svg; } From e8bdab05840584553924dc3e58ea8f17b06f39f6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 16:45:27 +0200 Subject: [PATCH 010/364] active indent guide --- src/vs/base/browser/ui/tree/abstractTree.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 8a4f178c3017f..f26454951c8d0 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1349,7 +1349,8 @@ export abstract class AbstractTree implements IDisposable const content: string[] = []; if (styles.treeIndentGuidesStroke) { - content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke}; }`); + content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.3)}; }`); + content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); } const newStyles = content.join('\n'); From 9ac764093a147d40d98d1b18975207dce72d3e4c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 16:55:33 +0200 Subject: [PATCH 011/364] remove indent modes --- src/vs/base/browser/ui/tree/abstractTree.ts | 135 +------------------- 1 file changed, 7 insertions(+), 128 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index f26454951c8d0..f37d318f11ebf 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -197,66 +197,11 @@ interface ITreeRendererOptions { readonly indent?: number; } -enum IndentGuide { - None, - First, - Middle, - Last -} - -function getLastVisibleChild(node: ITreeNode): ITreeNode | undefined { - for (let i = 0; i < node.children.length; i++) { - const child = node.children[node.children.length - i - 1]; - - if (child.visible) { - return child; - } - } - - return undefined; -} - -function getLastVisibleDescendant(node: ITreeNode): ITreeNode | undefined { - if (node.collapsed) { - return node; - } - - for (let i = 0; i < node.children.length; i++) { - const child = node.children[node.children.length - i - 1]; - - if (child.visible) { - return getLastVisibleDescendant(child); - } - } - - return undefined; -} - -function hasVisibleChildren(node: ITreeNode): boolean { - for (let i = 0; i < node.children.length; i++) { - if (node.children[i].visible) { - return true; - } - } - - return false; -} - interface IRenderData { templateData: ITreeListTemplateData; height: number; } -//********************************************* DEMO ************************* -enum Mode { - Brackets, - SubtreeBrackets, - Editor -} - -const mode: Mode = Mode.Editor; -//********************************************* DEMO ************************* - class TreeRenderer implements IListRenderer, ITreeListTemplateData> { private static DefaultIndent = 8; @@ -373,80 +318,14 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { - let parent: ITreeNode | undefined; - const guides: IndentGuide[] = []; - - if (target && target.collapsible && !target.collapsed && hasVisibleChildren(target)) { - guides.push(IndentGuide.First); - } else { - guides.push(IndentGuide.None); - } - - let node: ITreeNode | undefined = target; - - while (node) { - parent = node.parent; - - if (!parent || !parent.parent) { - break; - } - - switch (mode) { - case Mode.Brackets: - if (getLastVisibleChild(parent) === node) { - if (node === target) { - guides.push(IndentGuide.Last); - } else { - guides.push(IndentGuide.None); - } - } else { - guides.push(IndentGuide.Middle); - } - break; - case Mode.SubtreeBrackets: - if (getLastVisibleDescendant(parent) === target) { - guides.push(IndentGuide.Last); - } else { - guides.push(IndentGuide.Middle); - } - break; - case Mode.Editor: - guides.push(IndentGuide.Middle); - break; - } - - node = parent; - } - - const lines: string[] = []; - const halfHeight = Math.floor(height / 2); - - for (let i = 0; i < guides.length; i++) { - const x1 = Math.floor((guides.length - i - 1) * this.indent) + (mode === Mode.Editor ? 6 : 0); - const x2 = x1 + this.indent - Math.min(Math.floor(this.indent * 0.5), 4); - - switch (guides[i]) { - case IndentGuide.First: - if (mode === Mode.Editor) { - lines.push(``); - } else { - lines.push(``); - lines.push(``); - } - break; - case IndentGuide.Middle: - lines.push(``); - break; - case IndentGuide.Last: - lines.push(``); - lines.push(``); - break; - } - } + private renderIndentGuides(node: ITreeNode, templateData: ITreeListTemplateData, height: number): void { + const lines = range(1, node.depth).map(i => { + const x = Math.floor((node.depth - i - 1) * this.indent) + 6; + return ``; + }); - const width = this.indent * guides.length; - const svg = `${lines.join('')}`; + const width = this.indent * node.depth; + const svg = `${lines}`; templateData.indent.innerHTML = svg; } From 0ff18b817070264f9636fd0375643f03f82cd97c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 17:16:41 +0200 Subject: [PATCH 012/364] hover feedback --- src/vs/base/browser/ui/tree/abstractTree.ts | 4 ++-- src/vs/base/browser/ui/tree/media/tree.css | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index f37d318f11ebf..8ca3217e6f3ab 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1228,8 +1228,8 @@ export abstract class AbstractTree implements IDisposable const content: string[] = []; if (styles.treeIndentGuidesStroke) { - content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.3)}; }`); - content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); + content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.3)}; }`); + content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); } const newStyles = content.join('\n'); diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 1fcd3853819ba..f19695f2fcbf0 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -78,4 +78,9 @@ .hc-black .monaco-tl-twistie.loading { background-image: url("loading-hc.svg"); +} + +.monaco-list .monaco-tl-indent > svg > line { + stroke: transparent; + transition: stroke 0.15s linear; } \ No newline at end of file From 82548c0a2648b0ed4e878acbbbea961ab39a1668 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 17:18:46 +0200 Subject: [PATCH 013/364] :lipstick: --- src/vs/base/browser/ui/tree/abstractTree.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 8ca3217e6f3ab..230a13227021a 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1064,7 +1064,6 @@ export abstract class AbstractTree implements IDisposable get filterOnType(): boolean { return !!this._options.filterOnType; } get onDidChangeTypeFilterPattern(): Event { return this.typeFilterController ? this.typeFilterController.onDidChangePattern : Event.None; } - // Options TODO@joao expose options only, not Optional<> get openOnSingleClick(): boolean { return typeof this._options.openOnSingleClick === 'undefined' ? true : this._options.openOnSingleClick; } get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { return typeof this._options.expandOnlyOnTwistieClick === 'undefined' ? false : this._options.expandOnlyOnTwistieClick; } From 2e2a17035405e723648f2b67c2a479485a7d83c6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 17:21:14 +0200 Subject: [PATCH 014/364] remove extra event data from bracket indents --- src/vs/base/browser/ui/tree/abstractTree.ts | 8 +------- src/vs/base/browser/ui/tree/indexTreeModel.ts | 2 +- src/vs/base/browser/ui/tree/tree.ts | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 230a13227021a..c35f43d8eea88 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -214,7 +214,6 @@ class TreeRenderer implements IListRenderer, - onDidSplice: Event>, onDidChangeCollapseState: Event>, options: ITreeRendererOptions = {} ) { @@ -223,9 +222,6 @@ class TreeRenderer implements IListRenderer e.node)(this.onDidChangeNodeTwistieState, this, this.disposables); - // TODO: only do iff indent guides are enabled - Event.map(onDidSplice, e => e.parentNode)(this.onDidChangeNodeTwistieState, this, this.disposables); - if (renderer.onDidChangeTwistieState) { renderer.onDidChangeTwistieState(this.onDidChangeTwistieState, this, this.disposables); } @@ -1080,9 +1076,8 @@ export abstract class AbstractTree implements IDisposable ) { const treeDelegate = new ComposedTreeDelegate>(delegate); - const onDidSplice = new Relay>(); const onDidChangeCollapseStateRelay = new Relay>(); - this.renderers = renderers.map(r => new TreeRenderer(r, onDidSplice.event, onDidChangeCollapseStateRelay.event, _options)); + this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, _options)); this.disposables.push(...this.renderers); let filter: TypeFilter | undefined; @@ -1098,7 +1093,6 @@ export abstract class AbstractTree implements IDisposable this.view = new TreeNodeList(container, treeDelegate, this.renderers, this.focus, this.selection, { ...asListOptions(() => this.model, _options), tree: this }); this.model = this.createModel(this.view, _options); - onDidSplice.input = this.model.onDidSplice; onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState; this.model.onDidSplice(e => { diff --git a/src/vs/base/browser/ui/tree/indexTreeModel.ts b/src/vs/base/browser/ui/tree/indexTreeModel.ts index 33e5e8c31d6bf..a568881e7c2ff 100644 --- a/src/vs/base/browser/ui/tree/indexTreeModel.ts +++ b/src/vs/base/browser/ui/tree/indexTreeModel.ts @@ -171,7 +171,7 @@ export class IndexTreeModel, TFilterData = voi } const result = Iterator.map(Iterator.fromArray(deletedNodes), treeNodeToElement); - this._onDidSplice.fire({ parentNode, insertedNodes: nodesToInsert, deletedNodes }); + this._onDidSplice.fire({ insertedNodes: nodesToInsert, deletedNodes }); return result; } diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index b6f7a55610162..80b30fa4c559d 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -98,7 +98,6 @@ export interface ICollapseStateChangeEvent { } export interface ITreeModelSpliceEvent { - parentNode: ITreeNode; insertedNodes: ITreeNode[]; deletedNodes: ITreeNode[]; } From 1f97407f41ea8eb0b9a4cd9bed107c7a27b07ba6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 17:23:05 +0200 Subject: [PATCH 015/364] :lipstick: --- src/vs/base/browser/ui/tree/abstractTree.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index c35f43d8eea88..c7ee020168fe4 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -315,10 +315,9 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { - const lines = range(1, node.depth).map(i => { - const x = Math.floor((node.depth - i - 1) * this.indent) + 6; - return ``; - }); + const lines = range(1, node.depth) + .map(i => Math.floor((node.depth - i - 1) * this.indent) + 6) + .map(x => ``); const width = this.indent * node.depth; const svg = `${lines}`; From a4ac3aa289ec50008c2bab712a5d095731bdf8b9 Mon Sep 17 00:00:00 2001 From: Patrick Burke Date: Fri, 14 Jun 2019 22:02:14 +0200 Subject: [PATCH 016/364] Makes status zoom button a IStatusbarEntry #74454 ZoomStatusbarItem can now be instantiated, which is done in InlineImageView, which it uses to update the status bar. The needed services are passed down via constructors, starting in BaseBinaryResourceEditor. Removes padding from CSS which was necessary because of previous implementation. --- .../browser/parts/editor/binaryEditor.ts | 8 +- .../parts/editor/editor.contribution.ts | 13 --- .../parts/editor/media/resourceviewer.css | 4 - .../browser/parts/editor/resourceViewer.ts | 95 ++++++++----------- .../browser/parts/statusbar/statusbarPart.ts | 1 + .../files/browser/editors/binaryFileEditor.ts | 6 ++ 6 files changed, 54 insertions(+), 73 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/binaryEditor.ts b/src/vs/workbench/browser/parts/editor/binaryEditor.ts index b8a8325af3931..fd12b0179c1e3 100644 --- a/src/vs/workbench/browser/parts/editor/binaryEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryEditor.ts @@ -20,6 +20,8 @@ import { dispose } from 'vs/base/common/lifecycle'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IFileService } from 'vs/platform/files/common/files'; +import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; export interface IOpenCallbacks { openInternal: (input: EditorInput, options: EditorOptions) => Promise; @@ -50,7 +52,9 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor { themeService: IThemeService, @IFileService private readonly fileService: IFileService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, - @IStorageService storageService: IStorageService + @IStorageService storageService: IStorageService, + @IStatusbarService private readonly statusbarService: IStatusbarService, + @IContextMenuService private readonly contextMenuService: IContextMenuService ) { super(id, telemetryService, themeService, storageService); @@ -97,7 +101,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor { openInternalClb: () => this.handleOpenInternalCallback(input, options), openExternalClb: this.environmentService.configuration.remoteAuthority ? undefined : resource => this.callbacks.openExternal(resource), metadataClb: meta => this.handleMetadataChanged(meta) - }); + }, this.statusbarService, this.contextMenuService); } private async handleOpenInternalCallback(input: EditorInput, options: EditorOptions): Promise { diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 5c37926ade2a6..82e919d0d2ab3 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -8,8 +8,6 @@ import * as nls from 'vs/nls'; import { URI, UriComponents } from 'vs/base/common/uri'; import { Action, IAction } from 'vs/base/common/actions'; import { IEditorQuickOpenEntry, IQuickOpenRegistry, Extensions as QuickOpenExtensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; -import { StatusbarItemDescriptor, IStatusbarRegistry, Extensions as StatusExtensions } from 'vs/workbench/browser/parts/statusbar/statusbar'; -import { StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar'; import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { EditorInput, IEditorInputFactory, SideBySideEditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions, TextCompareEditorActiveContext, EditorPinnedContext, EditorGroupEditorsCountContext } from 'vs/workbench/common/editor'; import { TextResourceEditor } from 'vs/workbench/browser/parts/editor/textResourceEditor'; @@ -49,7 +47,6 @@ import { isMacintosh } from 'vs/base/common/platform'; import { AllEditorsPicker, ActiveEditorGroupPicker } from 'vs/workbench/browser/parts/editor/editorPicker'; import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { OpenWorkspaceButtonContribution } from 'vs/workbench/browser/parts/editor/editorWidgets'; -import { ZoomStatusbarItem } from 'vs/workbench/browser/parts/editor/resourceViewer'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { toLocalResource } from 'vs/base/common/resources'; import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; @@ -224,16 +221,6 @@ registerEditorContribution(OpenWorkspaceButtonContribution); // Register Editor Status Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(EditorStatus, LifecyclePhase.Ready); -// Register Zoom Status -const statusBar = Registry.as(StatusExtensions.Statusbar); -statusBar.registerStatusbarItem(new StatusbarItemDescriptor( - ZoomStatusbarItem, - 'status.imageZoom', - nls.localize('status.imageZoom', "Image Zoom"), - StatusbarAlignment.RIGHT, - 101 /* to the left of editor status (100) */) -); - // Register Status Actions const registry = Registry.as(ActionExtensions.WorkbenchActions); registry.registerWorkbenchAction(new SyncActionDescriptor(ChangeModeAction, ChangeModeAction.ID, ChangeModeAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_M) }), 'Change Language Mode'); diff --git a/src/vs/workbench/browser/parts/editor/media/resourceviewer.css b/src/vs/workbench/browser/parts/editor/media/resourceviewer.css index af8cc51704a9c..b6f7b107db7b9 100644 --- a/src/vs/workbench/browser/parts/editor/media/resourceviewer.css +++ b/src/vs/workbench/browser/parts/editor/media/resourceviewer.css @@ -58,10 +58,6 @@ cursor: zoom-out; } -.monaco-workbench .part.statusbar > .items-container > .statusbar-item > a.zoom-statusbar-item { - padding: 0 5px 0 5px; -} - .monaco-resource-viewer .embedded-link, .monaco-resource-viewer .embedded-link:hover { cursor: pointer; diff --git a/src/vs/workbench/browser/parts/editor/resourceViewer.ts b/src/vs/workbench/browser/parts/editor/resourceViewer.ts index 65b7706e60d7a..a3772c915a922 100644 --- a/src/vs/workbench/browser/parts/editor/resourceViewer.ts +++ b/src/vs/workbench/browser/parts/editor/resourceViewer.ts @@ -12,16 +12,13 @@ import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableEle import { LRUCache } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; import { clamp } from 'vs/base/common/numbers'; -import { Themable } from 'vs/workbench/common/theme'; -import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IDisposable, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Action } from 'vs/base/common/actions'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { memoize } from 'vs/base/common/decorators'; import * as platform from 'vs/base/common/platform'; import { IFileService } from 'vs/platform/files/common/files'; +import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar'; export interface IResourceDescriptor { readonly resource: URI; @@ -81,7 +78,9 @@ export class ResourceViewer { fileService: IFileService, container: HTMLElement, scrollbar: DomScrollableElement, - delegate: ResourceViewerDelegate + delegate: ResourceViewerDelegate, + statusbarService: IStatusbarService, + contextMenuService: IContextMenuService ): ResourceViewerContext { // Ensure CSS class @@ -89,7 +88,7 @@ export class ResourceViewer { // Images if (ResourceViewer.isImageResource(descriptor)) { - return ImageView.create(container, descriptor, fileService, scrollbar, delegate); + return ImageView.create(container, descriptor, fileService, scrollbar, delegate, statusbarService, contextMenuService); } // Large Files @@ -120,10 +119,12 @@ class ImageView { descriptor: IResourceDescriptor, fileService: IFileService, scrollbar: DomScrollableElement, - delegate: ResourceViewerDelegate + delegate: ResourceViewerDelegate, + statusbarService: IStatusbarService, + contextMenuService: IContextMenuService ): ResourceViewerContext { if (ImageView.shouldShowImageInline(descriptor)) { - return InlineImageView.create(container, descriptor, fileService, scrollbar, delegate); + return InlineImageView.create(container, descriptor, fileService, scrollbar, delegate, statusbarService, contextMenuService); } return LargeImageView.create(container, descriptor, delegate); @@ -234,71 +235,52 @@ class FileSeemsBinaryFileView { type Scale = number | 'fit'; -export class ZoomStatusbarItem extends Themable implements IStatusbarItem { - - static instance: ZoomStatusbarItem; +export class ZoomStatusbarItem extends Disposable { - private showTimeout: any; + private statusbarItem: IStatusbarEntryAccessor; - private statusBarItem: HTMLElement; - private onSelectScale?: (scale: Scale) => void; + onSelectScale?: (scale: Scale) => void; constructor( - @IContextMenuService private readonly contextMenuService: IContextMenuService, - @IEditorService editorService: IEditorService, - @IThemeService themeService: IThemeService + private readonly contextMenuService: IContextMenuService, + private readonly statusbarService: IStatusbarService ) { - super(themeService); - - ZoomStatusbarItem.instance = this; - - this._register(editorService.onDidActiveEditorChange(() => this.onActiveEditorChanged())); + super(); } - private onActiveEditorChanged(): void { - this.hide(); - this.onSelectScale = undefined; - } + updateStatusbar(scale: Scale, onSelectScale?: (scale: Scale) => void): void { + const entry: IStatusbarEntry = { + text: this.zoomLabel(scale) + }; - show(scale: Scale, onSelectScale: (scale: number) => void) { - clearTimeout(this.showTimeout); - this.showTimeout = setTimeout(() => { + if (onSelectScale) { this.onSelectScale = onSelectScale; - this.statusBarItem.style.display = 'block'; - this.updateLabel(scale); - }, 0); - } + } - hide() { - this.statusBarItem.style.display = 'none'; - } + if (!this.statusbarItem) { + this.statusbarItem = this.statusbarService.addEntry(entry, 'status.imageZoom', nls.localize('status.imageZoom', "Image Zoom"), StatusbarAlignment.RIGHT, 101 /* to the left of editor status (100) */); + + this._register(this.statusbarItem); - render(container: HTMLElement): IDisposable { - if (!this.statusBarItem && container) { - this.statusBarItem = DOM.append(container, DOM.$('a.zoom-statusbar-item')); - this.statusBarItem.setAttribute('role', 'button'); - this.statusBarItem.style.display = 'none'; + const element = document.getElementById('status.imageZoom')!; - DOM.addDisposableListener(this.statusBarItem, DOM.EventType.CLICK, () => { + this._register(DOM.addDisposableListener(element, DOM.EventType.CLICK, (e: MouseEvent) => { this.contextMenuService.showContextMenu({ - getAnchor: () => container, + getAnchor: () => element, getActions: () => this.zoomActions }); - }); + })); + } else { + this.statusbarItem.update(entry); } - - return this; - } - - private updateLabel(scale: Scale) { - this.statusBarItem.textContent = ZoomStatusbarItem.zoomLabel(scale); } @memoize private get zoomActions(): Action[] { const scales: Scale[] = [10, 5, 2, 1, 0.5, 0.2, 'fit']; return scales.map(scale => - new Action(`zoom.${scale}`, ZoomStatusbarItem.zoomLabel(scale), undefined, undefined, () => { + new Action(`zoom.${scale}`, this.zoomLabel(scale), undefined, undefined, () => { + this.updateStatusbar(scale); if (this.onSelectScale) { this.onSelectScale(scale); } @@ -307,7 +289,7 @@ export class ZoomStatusbarItem extends Themable implements IStatusbarItem { })); } - private static zoomLabel(scale: Scale): string { + private zoomLabel(scale: Scale): string { return scale === 'fit' ? nls.localize('zoom.action.fit.label', 'Whole Image') : `${Math.round(scale * 100)}%`; @@ -361,10 +343,15 @@ class InlineImageView { descriptor: IResourceDescriptor, fileService: IFileService, scrollbar: DomScrollableElement, - delegate: ResourceViewerDelegate + delegate: ResourceViewerDelegate, + statusbarService: IStatusbarService, + contextMenuService: IContextMenuService ) { const disposables = new DisposableStore(); + const zoomStatusbarItem = new ZoomStatusbarItem(contextMenuService, statusbarService); + disposables.add(zoomStatusbarItem); + const context: ResourceViewerContext = { layout(dimension: DOM.Dimension) { }, dispose: () => disposables.dispose() @@ -423,7 +410,7 @@ class InlineImageView { InlineImageView.imageStateCache.set(cacheKey, { scale: scale, offsetX: newScrollLeft, offsetY: newScrollTop }); } - ZoomStatusbarItem.instance.show(scale, updateScale); + zoomStatusbarItem.updateStatusbar(scale, updateScale); scrollbar.scanDomNode(); } diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index e41171068829b..dcc9d5da3de32 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -604,6 +604,7 @@ export class StatusbarPart extends Part implements IStatusbarService { private doCreateStatusItem(id: string, name: string, alignment: StatusbarAlignment, priority: number = 0, ...extraClasses: string[]): HTMLElement { const itemContainer = document.createElement('div'); itemContainer.title = name; + itemContainer.id = id; addClass(itemContainer, 'statusbar-item'); if (extraClasses) { diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index f9719911f6c41..6402c9fb41429 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -16,6 +16,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IFileService } from 'vs/platform/files/common/files'; +import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; /** * An implementation of editor for binary files like images. @@ -32,6 +34,8 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { @IStorageService storageService: IStorageService, @IFileService fileService: IFileService, @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @IStatusbarService statusbarService: IStatusbarService, + @IContextMenuService contextMenuService: IContextMenuService ) { super( BinaryFileEditor.ID, @@ -44,6 +48,8 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { fileService, environmentService, storageService, + statusbarService, + contextMenuService ); } From 3f6640e451546b53fe3773287fd82ff8de5040be Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 17:49:54 +0200 Subject: [PATCH 017/364] use DOM instead of innerHTML --- src/vs/base/browser/dom.ts | 27 ++++++++++++++++++--- src/vs/base/browser/ui/tree/abstractTree.ts | 21 +++++++++------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index c5f49f198e587..8aad714eb99c7 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -987,14 +987,28 @@ export function prepend(parent: HTMLElement, child: T): T { const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((.([\w\-]+))*)/; -export function $(description: string, attrs?: { [key: string]: any; }, ...children: Array): T { +export enum Namespace { + HTML = 'http://www.w3.org/1999/xhtml', + SVG = 'http://www.w3.org/2000/svg' +} + +function _$(namespace: Namespace, description: string, attrs?: { [key: string]: any; }, ...children: Array): T { let match = SELECTOR_REGEX.exec(description); if (!match) { throw new Error('Bad use of emmet'); } - let result = document.createElement(match[1] || 'div'); + attrs = { ...(attrs || {}) }; + + let tagName = match[1] || 'div'; + let result: T; + + if (namespace !== Namespace.HTML) { + result = document.createElementNS(namespace as string, tagName) as T; + } else { + result = document.createElement(tagName) as unknown as T; + } if (match[3]) { result.id = match[3]; @@ -1003,7 +1017,6 @@ export function $(description: string, attrs?: { [key: st result.className = match[4].replace(/\./g, ' ').trim(); } - attrs = attrs || {}; Object.keys(attrs).forEach(name => { const value = attrs![name]; if (/^on\w+$/.test(name)) { @@ -1030,6 +1043,14 @@ export function $(description: string, attrs?: { [key: st return result as T; } +export function $(description: string, attrs?: { [key: string]: any; }, ...children: Array): T { + return _$(Namespace.HTML, description, attrs, ...children); +} + +$.SVG = (description: string, attrs?: { [key: string]: any; }, ...children: Array) => { + return _$(Namespace.SVG, description, attrs, ...children); +}; + export function join(nodes: Node[], separator: Node | string): Node[] { const result: Node[] = []; diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index c7ee020168fe4..da09754d37de9 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -7,7 +7,7 @@ import 'vs/css!./media/tree'; import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IListOptions, List, IListStyles, mightProducePrintableCharacter, MouseController } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list'; -import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet } from 'vs/base/browser/dom'; +import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom'; import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event'; import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; @@ -313,16 +313,19 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { - const lines = range(1, node.depth) - .map(i => Math.floor((node.depth - i - 1) * this.indent) + 6) - .map(x => ``); - const width = this.indent * node.depth; - const svg = `${lines}`; + const svg = $.SVG('svg', { 'shape-rendering': 'crispEdges', width: `${width}`, height: `${height}`, viewBox: `0 0 ${width} ${height}` }); + + for (let i = 1; i < node.depth; i++) { + const x = Math.floor((node.depth - i - 1) * this.indent) + 6; + const line = $.SVG('line', { x1: x, y1: 0, x2: x, y2: height }); + svg.appendChild(line); + } - templateData.indent.innerHTML = svg; + clearNode(templateData.indent); + templateData.indent.appendChild(svg); } dispose(): void { @@ -1221,7 +1224,7 @@ export abstract class AbstractTree implements IDisposable if (styles.treeIndentGuidesStroke) { content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.3)}; }`); - content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); + content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); } const newStyles = content.join('\n'); From 0bb42e1c67c93b1e4c49f55b5a471e590d27541a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 17 Jun 2019 10:00:04 -0700 Subject: [PATCH 018/364] Update remote node-pty --- remote/package.json | 8 ++++---- remote/yarn.lock | 17 ++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/remote/package.json b/remote/package.json index da17913e867ed..acf5412a080d5 100644 --- a/remote/package.json +++ b/remote/package.json @@ -12,7 +12,7 @@ "keytar": "4.2.1", "minimist": "1.2.0", "native-watchdog": "1.0.0", - "node-pty": "0.8.1", + "node-pty": "0.9.0-beta17", "onigasm-umd": "^2.2.2", "semver": "^5.5.0", "spdlog": "^0.9.0", @@ -21,11 +21,11 @@ "vscode-proxy-agent": "0.4.0", "vscode-ripgrep": "^1.2.5", "vscode-textmate": "^4.1.1", - "yauzl": "^2.9.2", - "yazl": "^2.4.3", "xterm": "3.15.0-beta34", "xterm-addon-search": "0.1.0-beta6", - "xterm-addon-web-links": "0.1.0-beta10" + "xterm-addon-web-links": "0.1.0-beta10", + "yauzl": "^2.9.2", + "yazl": "^2.4.3" }, "optionalDependencies": { "vscode-windows-ca-certs": "0.1.0" diff --git a/remote/yarn.lock b/remote/yarn.lock index 11db8ed16fb9c..e5f73a8d3e641 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -599,11 +599,6 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -nan@2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" - integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== - nan@2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" @@ -614,7 +609,7 @@ nan@^2.10.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099" integrity sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw== -nan@^2.12.1, nan@^2.14.0: +nan@^2.12.1, nan@^2.13.2, nan@^2.14.0: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -636,12 +631,12 @@ node-addon-api@1.6.2: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.6.2.tgz#d8aad9781a5cfc4132cc2fecdbdd982534265217" integrity sha512-479Bjw9nTE5DdBSZZWprFryHGjUaQC31y1wHo19We/k0BZlrmhqQitWoUL0cD8+scljCbIUL+E58oRDEakdGGA== -node-pty@0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.8.1.tgz#94b457bec013e7a09b8d9141f63b0787fa25c23f" - integrity sha512-j+/g0Q5dR+vkELclpJpz32HcS3O/3EdPSGPvDXJZVJQLCvgG0toEbfmymxAEyQyZEpaoKHAcoL+PvKM+4N9nlw== +node-pty@0.9.0-beta17: + version "0.9.0-beta17" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0-beta17.tgz#9b490df86a8124dea595e9fbedeaaf4b2eedbbcb" + integrity sha512-E94XwIs3JxLKAboquHY9Kytbbj/T/tJtRpQoAUdfPE7UXRta/NV+xdmRNhZkeU9jCji+plm656GbYFievgNPkQ== dependencies: - nan "2.12.1" + nan "^2.13.2" noop-logger@^0.1.1: version "0.1.1" From a321476b277d6ce727e8a200b42ef7b4932be5de Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 17 Jun 2019 10:47:50 -0700 Subject: [PATCH 019/364] Disable shell selector on remote --- .../contrib/terminal/browser/terminal.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 2ab913b9cfc79..dfefd249327a7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -370,7 +370,8 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAct primary: 0, mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_K } }, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingWeight.WorkbenchContrib + 1), 'Terminal: Clear', category); -if (platform.isWindows) { +// TODO: Web should support this as well, the shell query needs to go to the ext host though +if (platform.isWindows && !platform.isWeb) { actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category); } actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowWorkspaceShellTerminalCommand, AllowWorkspaceShellTerminalCommand.ID, AllowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Allow Workspace Shell Configuration', category); From 7dfbccb8e213f93618206ae0799ee181b8464155 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 17 Jun 2019 10:48:03 -0700 Subject: [PATCH 020/364] Disable conpty on remote --- src/vs/workbench/api/node/extHostTerminalService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index f0dd94833f7da..eadd6cbdf7d92 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -534,7 +534,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Fork the process and listen for messages this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env); - const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, terminalConfig.get('windowsEnableConpty') as boolean, this._logService); + // TODO: Support conpty on remote, it doesn't seem to work for some reason? + const enableConpty = false; //terminalConfig.get('windowsEnableConpty') as boolean; + const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, enableConpty, this._logService); p.onProcessReady((e: { pid: number, cwd: string }) => this._proxy.$sendProcessReady(id, e.pid, e.cwd)); p.onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title)); p.onProcessData(data => this._proxy.$sendProcessData(id, data)); From c287c3cfc77a92429ffaf497935ea1a18e0720a3 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 17 Jun 2019 11:53:58 -0700 Subject: [PATCH 021/364] Get default shell selector working --- remote/package.json | 3 +- remote/yarn.lock | 7 ++ .../api/browser/mainThreadTerminalService.ts | 59 +++++----- .../workbench/api/common/extHost.protocol.ts | 6 + .../api/node/extHostTerminalService.ts | 13 ++- .../terminal/browser/terminal.contribution.ts | 8 +- .../terminal/browser/terminalActions.ts | 11 +- .../terminal/browser/terminalNativeService.ts | 9 +- .../terminal/browser/terminalService.ts | 8 +- .../contrib/terminal/common/terminal.ts | 10 +- .../terminal/common/terminalService.ts | 33 +++++- .../electron-browser/terminalNativeService.ts | 103 +----------------- .../contrib/terminal/node/terminal.ts | 71 +++++++++++- 13 files changed, 191 insertions(+), 150 deletions(-) diff --git a/remote/package.json b/remote/package.json index acf5412a080d5..7a48c4cb23835 100644 --- a/remote/package.json +++ b/remote/package.json @@ -28,6 +28,7 @@ "yazl": "^2.4.3" }, "optionalDependencies": { - "vscode-windows-ca-certs": "0.1.0" + "vscode-windows-ca-certs": "0.1.0", + "vscode-windows-registry": "1.0.1" } } diff --git a/remote/yarn.lock b/remote/yarn.lock index e5f73a8d3e641..6bf34b0726ac6 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -1112,6 +1112,13 @@ vscode-windows-ca-certs@0.1.0: dependencies: node-addon-api "1.6.2" +vscode-windows-registry@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vscode-windows-registry/-/vscode-windows-registry-1.0.1.tgz#bc9f765563eb6dc1c9ad9a41f9eaacc84dfadc7c" + integrity sha512-q0aKXi9Py1OBdmXIJJFeJBzpPJMMUxMJNBU9FysWIXEwJyMQGEVevKzM2J3Qz/cHSc5LVqibmoUWzZ7g+97qRg== + dependencies: + nan "^2.12.1" + which-pm-runs@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index a68310bb3ee88..2d9fba053ce41 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { UriComponents, URI } from 'vs/base/common/uri'; @@ -22,11 +22,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape constructor( extHostContext: IExtHostContext, - @ITerminalService private readonly terminalService: ITerminalService + @ITerminalService private readonly _terminalService: ITerminalService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._remoteAuthority = extHostContext.remoteAuthority; - this._toDispose.push(terminalService.onInstanceCreated((instance) => { + this._toDispose.push(_terminalService.onInstanceCreated((instance) => { // Delay this message so the TerminalInstance constructor has a chance to finish and // return the ID normally to the extension host. The ID that is passed here will be used // to register non-extension API terminals in the extension host. @@ -35,25 +35,26 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._onInstanceDimensionsChanged(instance); }, EXT_HOST_CREATION_DELAY); })); - this._toDispose.push(terminalService.onInstanceDisposed(instance => this._onTerminalDisposed(instance))); - this._toDispose.push(terminalService.onInstanceProcessIdReady(instance => this._onTerminalProcessIdReady(instance))); - this._toDispose.push(terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance))); - this._toDispose.push(terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request))); - this._toDispose.push(terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); - this._toDispose.push(terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); - this._toDispose.push(terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed))); + this._toDispose.push(_terminalService.onInstanceDisposed(instance => this._onTerminalDisposed(instance))); + this._toDispose.push(_terminalService.onInstanceProcessIdReady(instance => this._onTerminalProcessIdReady(instance))); + this._toDispose.push(_terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance))); + this._toDispose.push(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request))); + this._toDispose.push(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); + this._toDispose.push(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); + this._toDispose.push(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed))); + this._toDispose.push(_terminalService.onRequestWindowsShells(r => this._onRequestDetectWindowsShell(r))); // Set initial ext host state - this.terminalService.terminalInstances.forEach(t => { + this._terminalService.terminalInstances.forEach(t => { this._onTerminalOpened(t); t.processReady.then(() => this._onTerminalProcessIdReady(t)); }); - const activeInstance = this.terminalService.getActiveInstance(); + const activeInstance = this._terminalService.getActiveInstance(); if (activeInstance) { this._proxy.$acceptActiveTerminalChanged(activeInstance.id); } - this.terminalService.extHostReady(extHostContext.remoteAuthority); + this._terminalService.extHostReady(extHostContext.remoteAuthority); } public dispose(): void { @@ -75,7 +76,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape strictEnv, runInBackground }; - const terminal = this.terminalService.createTerminal(shellLaunchConfig); + const terminal = this._terminalService.createTerminal(shellLaunchConfig); return Promise.resolve({ id: terminal.id, name: terminal.title @@ -83,55 +84,55 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } public $createTerminalRenderer(name: string): Promise { - const instance = this.terminalService.createTerminalRenderer(name); + const instance = this._terminalService.createTerminalRenderer(name); return Promise.resolve(instance.id); } public $show(terminalId: number, preserveFocus: boolean): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance) { - this.terminalService.setActiveInstance(terminalInstance); - this.terminalService.showPanel(!preserveFocus); + this._terminalService.setActiveInstance(terminalInstance); + this._terminalService.showPanel(!preserveFocus); } } public $hide(terminalId: number): void { - const instance = this.terminalService.getActiveInstance(); + const instance = this._terminalService.getActiveInstance(); if (instance && instance.id === terminalId) { - this.terminalService.hidePanel(); + this._terminalService.hidePanel(); } } public $dispose(terminalId: number): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance) { terminalInstance.dispose(); } } public $terminalRendererWrite(terminalId: number, text: string): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance && terminalInstance.shellLaunchConfig.isRendererOnly) { terminalInstance.write(text); } } public $terminalRendererSetName(terminalId: number, name: string): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance && terminalInstance.shellLaunchConfig.isRendererOnly) { terminalInstance.setTitle(name, false); } } public $terminalRendererSetDimensions(terminalId: number, dimensions: ITerminalDimensions): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance && terminalInstance.shellLaunchConfig.isRendererOnly) { terminalInstance.setDimensions(dimensions); } } public $terminalRendererRegisterOnInputListener(terminalId: number): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (!terminalInstance) { return; } @@ -147,14 +148,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } public $sendText(terminalId: number, text: string, addNewLine: boolean): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (terminalInstance) { terminalInstance.sendText(text, addNewLine); } } public $registerOnDataListener(terminalId: number): void { - const terminalInstance = this.terminalService.getInstanceFromId(terminalId); + const terminalInstance = this._terminalService.getInstanceFromId(terminalId); if (!terminalInstance) { return; } @@ -275,4 +276,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } this._terminalProcesses[terminalId].emitLatency(sum / COUNT); } + + private _onRequestDetectWindowsShell(resolve: (shells: IShellDefinition[]) => void): void { + this._proxy.$requestWindowsShells().then(shells => resolve(shells)); + } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index bb93e4195687e..d21659ce49cb3 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1106,6 +1106,11 @@ export interface ShellLaunchConfigDto { env?: { [key: string]: string | null }; } +export interface IShellDefinitionDto { + label: string; + path: string; +} + export interface ExtHostTerminalServiceShape { $acceptTerminalClosed(id: number): void; $acceptTerminalOpened(id: number, name: string): void; @@ -1123,6 +1128,7 @@ export interface ExtHostTerminalServiceShape { $acceptProcessRequestCwd(id: number): void; $acceptProcessRequestLatency(id: number): number; $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; + $requestWindowsShells(): Promise; } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index eadd6cbdf7d92..d2693538cc63f 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -10,7 +10,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Event, Emitter } from 'vs/base/common/event'; -import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -20,7 +20,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getDefaultShell, detectWindowsShells } from 'vs/workbench/contrib/terminal/node/terminal'; const RENDERER_NO_PROCESS_ID = -1; @@ -575,6 +575,15 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return id; } + public $requestWindowsShells(): Promise { + console.log('$requestWindowsShells'); + if (!platform.isWindows) { + throw new Error('Can only detect Windows shells on Windows'); + } + console.log('$requestWindowsShells2'); + return detectWindowsShells(); + } + private _onProcessExit(id: number, exitCode: number): void { // Remove listeners this._terminalProcesses[id].dispose(); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index dfefd249327a7..db127081d5d1f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -370,10 +370,10 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAct primary: 0, mac: { primary: KeyMod.CtrlCmd | KeyCode.KEY_K } }, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingWeight.WorkbenchContrib + 1), 'Terminal: Clear', category); -// TODO: Web should support this as well, the shell query needs to go to the ext host though -if (platform.isWindows && !platform.isWeb) { - actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category); -} +// TODO: This should be the remote OS +// if (platform.isWindows) { +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(SelectDefaultShellWindowsTerminalAction, SelectDefaultShellWindowsTerminalAction.ID, SelectDefaultShellWindowsTerminalAction.LABEL), 'Terminal: Select Default Shell', category); +// } actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowWorkspaceShellTerminalCommand, AllowWorkspaceShellTerminalCommand.ID, AllowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Allow Workspace Shell Configuration', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowWorkspaceShellTerminalCommand, DisallowWorkspaceShellTerminalCommand.ID, DisallowWorkspaceShellTerminalCommand.LABEL), 'Terminal: Disallow Workspace Shell Configuration', category); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(RenameTerminalAction, RenameTerminalAction.ID, RenameTerminalAction.LABEL), 'Terminal: Rename', category); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 19d55b6508148..199d6b2183b46 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { Action, IAction } from 'vs/base/common/actions'; import { EndOfLinePreference } from 'vs/editor/common/model'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, Direction, ITerminalConfigHelper, ITerminalNativeService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, TERMINAL_PANEL_ID, ITerminalInstance, Direction, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { TogglePanelAction } from 'vs/workbench/browser/panel'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; @@ -624,13 +624,13 @@ export class SelectDefaultShellWindowsTerminalAction extends Action { constructor( id: string, label: string, - @ITerminalNativeService private readonly _terminalNativeService: ITerminalNativeService + @ITerminalService private readonly _terminalService: ITerminalService ) { super(id, label); } public run(event?: any): Promise { - return this._terminalNativeService.selectDefaultWindowsShell(); + return this._terminalService.selectDefaultWindowsShell(); } } @@ -712,8 +712,7 @@ export class SwitchTerminalAction extends Action { constructor( id: string, label: string, - @ITerminalService private readonly terminalService: ITerminalService, - @ITerminalNativeService private readonly terminalNativeService: ITerminalNativeService + @ITerminalService private readonly terminalService: ITerminalService ) { super(id, label, 'terminal-action switch-terminal'); } @@ -728,7 +727,7 @@ export class SwitchTerminalAction extends Action { } if (item === SelectDefaultShellWindowsTerminalAction.LABEL) { this.terminalService.refreshActiveTab(); - return this.terminalNativeService.selectDefaultWindowsShell(); + return this.terminalService.selectDefaultWindowsShell(); } const selectedTabIndex = parseInt(item.split(':')[0], 10) - 1; this.terminalService.setActiveTabByIndex(selectedTabIndex); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts b/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts index 0e2849731fc07..4d15ce7da31ad 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; -import { ITerminalNativeService, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalNativeService, LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; import { Emitter, Event } from 'vs/base/common/event'; export class TerminalNativeService implements ITerminalNativeService { @@ -23,15 +23,16 @@ export class TerminalNativeService implements ITerminalNativeService { throw new Error('Not implemented'); } - public selectDefaultWindowsShell(): Promise { + public getWslPath(): Promise { throw new Error('Not implemented'); } - public getWslPath(): Promise { + public getWindowsBuildNumber(): number { throw new Error('Not implemented'); } - public getWindowsBuildNumber(): number { + // TODO: Remove local impl + public detectWindowsShells(): Promise { throw new Error('Not implemented'); } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 00c2820793def..1e2017721bcc3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -21,6 +21,8 @@ import { TerminalInstance } from 'vs/workbench/contrib/terminal/browser/terminal import { IBrowserTerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; +import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export class TerminalService extends CommonTerminalService implements ITerminalService { private _configHelper: IBrowserTerminalConfigHelper; @@ -39,9 +41,11 @@ export class TerminalService extends CommonTerminalService implements ITerminalS @IExtensionService extensionService: IExtensionService, @IFileService fileService: IFileService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, - @ITerminalNativeService readonly terminalNativeService: ITerminalNativeService + @ITerminalNativeService readonly terminalNativeService: ITerminalNativeService, + @IQuickInputService readonly quickInputService: IQuickInputService, + @IConfigurationService readonly configurationService: IConfigurationService ) { - super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService, remoteAgentService, terminalNativeService); + super(contextKeyService, panelService, lifecycleService, storageService, notificationService, dialogService, extensionService, fileService, remoteAgentService, terminalNativeService, quickInputService, configurationService); this._configHelper = this._instantiationService.createInstance(TerminalConfigHelper, this.terminalNativeService.linuxDistro); } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index c66a35797f0db..7f7ba8436e15a 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -222,6 +222,7 @@ export interface ITerminalService { onInstancesChanged: Event; onInstanceTitleChanged: Event; onActiveInstanceChanged: Event; + onRequestWindowsShells: Event<(shells: IShellDefinition[]) => void>; /** * Creates a terminal. @@ -267,6 +268,8 @@ export interface ITerminalService { findNext(): void; findPrevious(): void; + selectDefaultWindowsShell(): Promise; + setContainers(panelContainer: HTMLElement, terminalContainer: HTMLElement): void; setWorkspaceShellAllowed(isAllowed: boolean): void; @@ -299,7 +302,12 @@ export interface ITerminalNativeService { getWindowsBuildNumber(): number; whenFileDeleted(path: URI): Promise; getWslPath(path: string): Promise; - selectDefaultWindowsShell(): Promise; + detectWindowsShells(): Promise; +} + +export interface IShellDefinition { + label: string; + path: string; } export const enum Direction { diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index c7da0cb4dbcfe..be79d920ce829 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID, ITerminalTab, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalNativeService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID, ITerminalTab, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalNativeService, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; @@ -22,6 +22,8 @@ import { basename } from 'vs/base/common/path'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { timeout } from 'vs/base/common/async'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; +import { IPickOptions, IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export abstract class TerminalService implements ITerminalService { public _serviceBrand: any; @@ -63,6 +65,8 @@ export abstract class TerminalService implements ITerminalService { public get onActiveInstanceChanged(): Event { return this._onActiveInstanceChanged.event; } protected readonly _onTabDisposed = new Emitter(); public get onTabDisposed(): Event { return this._onTabDisposed.event; } + protected readonly _onRequestWindowsShells = new Emitter<(shells: IShellDefinition[]) => void>(); + public get onRequestWindowsShells(): Event<(shells: IShellDefinition[]) => void> { return this._onRequestWindowsShells.event; } public abstract get configHelper(): ITerminalConfigHelper; @@ -76,7 +80,9 @@ export abstract class TerminalService implements ITerminalService { @IExtensionService private readonly _extensionService: IExtensionService, @IFileService protected readonly _fileService: IFileService, @IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService, - @ITerminalNativeService private readonly _terminalNativeService: ITerminalNativeService + @ITerminalNativeService private readonly _terminalNativeService: ITerminalNativeService, + @IQuickInputService private readonly _quickInputService: IQuickInputService, + @IConfigurationService private readonly _configurationService: IConfigurationService ) { this._activeTabIndex = 0; this._isShuttingDown = false; @@ -522,4 +528,27 @@ export abstract class TerminalService implements ITerminalService { c(escapeNonWindowsPath(originalPath)); }); } + + public selectDefaultWindowsShell(): Promise { + return this._detectWindowsShells().then(shells => { + const options: IPickOptions = { + placeHolder: nls.localize('terminal.integrated.chooseWindowsShell', "Select your preferred terminal shell, you can change this later in your settings") + }; + const quickPickItems = shells.map(s => { + return { label: s.label, description: s.path }; + }); + return this._quickInputService.pick(quickPickItems, options).then(async value => { + if (!value) { + return undefined; + } + const shell = value.description; + await this._configurationService.updateValue('terminal.integrated.shell.windows', shell, ConfigurationTarget.USER).then(() => shell); + return Promise.resolve(); + }); + }); + } + + private _detectWindowsShells(): Promise { + return new Promise(r => this._onRequestWindowsShells.fire(r)); + } } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts index 68b7462447a78..4eba4ead96195 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts @@ -3,19 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; import { ipcRenderer as ipc } from 'electron'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; -import { ITerminalNativeService, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalNativeService, LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; import { URI } from 'vs/base/common/uri'; import { IFileService } from 'vs/platform/files/common/files'; -import { getWindowsBuildNumber, linuxDistro } from 'vs/workbench/contrib/terminal/node/terminal'; -import { IQuickPickItem, IPickOptions, IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; +import { getWindowsBuildNumber, linuxDistro, detectWindowsShells } from 'vs/workbench/contrib/terminal/node/terminal'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { execFile } from 'child_process'; -import { coalesce } from 'vs/base/common/arrays'; import { Emitter, Event } from 'vs/base/common/event'; -import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class TerminalNativeService implements ITerminalNativeService { @@ -30,8 +26,6 @@ export class TerminalNativeService implements ITerminalNativeService { constructor( @IFileService private readonly _fileService: IFileService, - @IQuickInputService private readonly _quickInputService: IQuickInputService, - @IConfigurationService private readonly _configurationService: IConfigurationService, @IInstantiationService readonly instantiationService: IInstantiationService, ) { ipc.on('vscode:openFiles', (_event: any, request: IOpenFileRequest) => this._onOpenFileRequest.fire(request)); @@ -58,97 +52,8 @@ export class TerminalNativeService implements ITerminalNativeService { }); } - public selectDefaultWindowsShell(): Promise { - return this._detectWindowsShells().then(shells => { - const options: IPickOptions = { - placeHolder: nls.localize('terminal.integrated.chooseWindowsShell', "Select your preferred terminal shell, you can change this later in your settings") - }; - return this._quickInputService.pick(shells, options).then(value => { - if (!value) { - return undefined; - } - const shell = value.description; - return this._configurationService.updateValue('terminal.integrated.shell.windows', shell, ConfigurationTarget.USER).then(() => shell); - }); - }); - } - - /** - * Get the executable file path of shell from registry. - * @param shellName The shell name to get the executable file path - * @returns `[]` or `[ 'path' ]` - */ - private async _getShellPathFromRegistry(shellName: string): Promise { - const Registry = await import('vscode-windows-registry'); - - try { - const shellPath = Registry.GetStringRegKey('HKEY_LOCAL_MACHINE', `SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${shellName}.exe`, ''); - - if (shellPath === undefined) { - return []; - } - - return [shellPath]; - } catch (error) { - return []; - } - } - - private async _detectWindowsShells(): Promise { - // Determine the correct System32 path. We want to point to Sysnative - // when the 32-bit version of VS Code is running on a 64-bit machine. - // The reason for this is because PowerShell's important PSReadline - // module doesn't work if this is not the case. See #27915. - const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); - const system32Path = `${process.env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}`; - - let useWSLexe = false; - - if (getWindowsBuildNumber() >= 16299) { - useWSLexe = true; - } - - const expectedLocations = { - 'Command Prompt': [`${system32Path}\\cmd.exe`], - PowerShell: [`${system32Path}\\WindowsPowerShell\\v1.0\\powershell.exe`], - 'PowerShell Core': await this._getShellPathFromRegistry('pwsh'), - 'WSL Bash': [`${system32Path}\\${useWSLexe ? 'wsl.exe' : 'bash.exe'}`], - 'Git Bash': [ - `${process.env['ProgramW6432']}\\Git\\bin\\bash.exe`, - `${process.env['ProgramW6432']}\\Git\\usr\\bin\\bash.exe`, - `${process.env['ProgramFiles']}\\Git\\bin\\bash.exe`, - `${process.env['ProgramFiles']}\\Git\\usr\\bin\\bash.exe`, - `${process.env['LocalAppData']}\\Programs\\Git\\bin\\bash.exe`, - ] - }; - const promises: PromiseLike<[string, string]>[] = []; - Object.keys(expectedLocations).forEach(key => promises.push(this._validateShellPaths(key, expectedLocations[key]))); - return Promise.all(promises) - .then(coalesce) - .then(results => { - return results.map(result => { - return { - label: result[0], - description: result[1] - }; - }); - }); - } - - private _validateShellPaths(label: string, potentialPaths: string[]): Promise<[string, string] | null> { - if (potentialPaths.length === 0) { - return Promise.resolve(null); - } - const current = potentialPaths.shift(); - if (current! === '') { - return this._validateShellPaths(label, potentialPaths); - } - return this._fileService.exists(URI.file(current!)).then(exists => { - if (!exists) { - return this._validateShellPaths(label, potentialPaths); - } - return [label, current] as [string, string]; - }); + public detectWindowsShells(): Promise { + return detectWindowsShells(); } /** diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index 493fad0b8332e..b1610199f3dd9 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -6,8 +6,10 @@ import * as os from 'os'; import * as platform from 'vs/base/common/platform'; import * as processes from 'vs/base/node/processes'; -import { readFile, fileExists } from 'vs/base/node/pfs'; -import { LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; +import { readFile, fileExists, stat } from 'vs/base/node/pfs'; +import { LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; +import { coalesce } from 'vs/base/common/arrays'; +import { normalize } from 'vs/base/common/path'; export function getDefaultShell(p: platform.Platform): string { if (p === platform.Platform.Windows) { @@ -82,3 +84,68 @@ export function getWindowsBuildNumber(): number { } return buildNumber; } + +export async function detectWindowsShells(): Promise { + console.log('a'); + // Determine the correct System32 path. We want to point to Sysnative + // when the 32-bit version of VS Code is running on a 64-bit machine. + // The reason for this is because PowerShell's important PSReadline + // module doesn't work if this is not the case. See #27915. + const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); + const system32Path = `${process.env['windir']}\\${is32ProcessOn64Windows ? 'Sysnative' : 'System32'}`; + + let useWSLexe = false; + + if (getWindowsBuildNumber() >= 16299) { + useWSLexe = true; + } + + const expectedLocations = { + 'Command Prompt': [`${system32Path}\\cmd.exe`], + PowerShell: [`${system32Path}\\WindowsPowerShell\\v1.0\\powershell.exe`], + 'PowerShell Core': [await getShellPathFromRegistry('pwsh')], + 'WSL Bash': [`${system32Path}\\${useWSLexe ? 'wsl.exe' : 'bash.exe'}`], + 'Git Bash': [ + `${process.env['ProgramW6432']}\\Git\\bin\\bash.exe`, + `${process.env['ProgramW6432']}\\Git\\usr\\bin\\bash.exe`, + `${process.env['ProgramFiles']}\\Git\\bin\\bash.exe`, + `${process.env['ProgramFiles']}\\Git\\usr\\bin\\bash.exe`, + `${process.env['LocalAppData']}\\Programs\\Git\\bin\\bash.exe`, + ] + }; + const promises: PromiseLike[] = []; + Object.keys(expectedLocations).forEach(key => promises.push(validateShellPaths(key, expectedLocations[key]))); + + console.log('$detectWindowsShells'); + return Promise.all(promises).then(coalesce); +} + + +function validateShellPaths(label: string, potentialPaths: string[]): Promise { + if (potentialPaths.length === 0) { + return Promise.resolve(undefined); + } + const current = potentialPaths.shift()!; + if (current! === '') { + return validateShellPaths(label, potentialPaths); + } + return stat(normalize(current)).then(stat => { + if (!stat.isFile && !stat.isSymbolicLink) { + return validateShellPaths(label, potentialPaths); + } + return { + label, + path: current + }; + }); +} + +async function getShellPathFromRegistry(shellName: string): Promise { + const Registry = await import('vscode-windows-registry'); + try { + const shellPath = Registry.GetStringRegKey('HKEY_LOCAL_MACHINE', `SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\${shellName}.exe`, ''); + return shellPath ? shellPath : ''; + } catch (error) { + return ''; + } +} \ No newline at end of file From d0820c2e0674c457e5eb318681e8452f645e1cfe Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 17 Jun 2019 11:54:34 -0700 Subject: [PATCH 022/364] Disable old shell detection mechanism --- src/vs/workbench/api/node/extHostTerminalService.ts | 2 -- .../contrib/terminal/browser/terminalNativeService.ts | 7 +------ src/vs/workbench/contrib/terminal/common/terminal.ts | 1 - .../terminal/electron-browser/terminalNativeService.ts | 8 ++------ src/vs/workbench/contrib/terminal/node/terminal.ts | 2 -- 5 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index d2693538cc63f..6274c89b139cc 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -576,11 +576,9 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } public $requestWindowsShells(): Promise { - console.log('$requestWindowsShells'); if (!platform.isWindows) { throw new Error('Can only detect Windows shells on Windows'); } - console.log('$requestWindowsShells2'); return detectWindowsShells(); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts b/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts index 4d15ce7da31ad..2ed3246317c67 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalNativeService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; -import { ITerminalNativeService, LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalNativeService, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import { Emitter, Event } from 'vs/base/common/event'; export class TerminalNativeService implements ITerminalNativeService { @@ -30,9 +30,4 @@ export class TerminalNativeService implements ITerminalNativeService { public getWindowsBuildNumber(): number { throw new Error('Not implemented'); } - - // TODO: Remove local impl - public detectWindowsShells(): Promise { - throw new Error('Not implemented'); - } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 7f7ba8436e15a..205ce54cebc8a 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -302,7 +302,6 @@ export interface ITerminalNativeService { getWindowsBuildNumber(): number; whenFileDeleted(path: URI): Promise; getWslPath(path: string): Promise; - detectWindowsShells(): Promise; } export interface IShellDefinition { diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts index 4eba4ead96195..423284f97a533 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts @@ -5,10 +5,10 @@ import { ipcRenderer as ipc } from 'electron'; import { IOpenFileRequest } from 'vs/platform/windows/common/windows'; -import { ITerminalNativeService, LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalNativeService, LinuxDistro } from 'vs/workbench/contrib/terminal/common/terminal'; import { URI } from 'vs/base/common/uri'; import { IFileService } from 'vs/platform/files/common/files'; -import { getWindowsBuildNumber, linuxDistro, detectWindowsShells } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getWindowsBuildNumber, linuxDistro } from 'vs/workbench/contrib/terminal/node/terminal'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { execFile } from 'child_process'; import { Emitter, Event } from 'vs/base/common/event'; @@ -52,10 +52,6 @@ export class TerminalNativeService implements ITerminalNativeService { }); } - public detectWindowsShells(): Promise { - return detectWindowsShells(); - } - /** * Converts a path to a path on WSL using the wslpath utility. * @param path The original path. diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index b1610199f3dd9..979a359e8b534 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -86,7 +86,6 @@ export function getWindowsBuildNumber(): number { } export async function detectWindowsShells(): Promise { - console.log('a'); // Determine the correct System32 path. We want to point to Sysnative // when the 32-bit version of VS Code is running on a 64-bit machine. // The reason for this is because PowerShell's important PSReadline @@ -116,7 +115,6 @@ export async function detectWindowsShells(): Promise { const promises: PromiseLike[] = []; Object.keys(expectedLocations).forEach(key => promises.push(validateShellPaths(key, expectedLocations[key]))); - console.log('$detectWindowsShells'); return Promise.all(promises).then(coalesce); } From 4375d8391f70b558d32907a559ea0a5fe0c44d97 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 17 Jun 2019 21:57:53 +0200 Subject: [PATCH 023/364] less transparent --- src/vs/base/browser/ui/tree/abstractTree.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index da09754d37de9..b9a7d25da9fd8 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1223,7 +1223,7 @@ export abstract class AbstractTree implements IDisposable const content: string[] = []; if (styles.treeIndentGuidesStroke) { - content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.3)}; }`); + content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`); content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); } From 459939b9051e86653ef49f910c408a2b64f27bff Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 17 Jun 2019 15:39:56 -0700 Subject: [PATCH 024/364] Provide full TS symbol range when previewing definitions in VSCode Fixes #72017 Has two fixes: - Hooks up the JS/TS extension to consume the full symbol range provided by https://github.com/microsoft/TypeScript/pull/31587 - Makes the go the definition mouse implementation use the locationLink to compute the preview range. If a`targetSelectionRange` is provided, this means we use the normal `range` to get the preview range --- .../src/features/definitions.ts | 10 +++++++++- .../src/utils/typeConverters.ts | 7 +++++-- .../contrib/goToDefinition/goToDefinitionMouse.ts | 10 +++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/extensions/typescript-language-features/src/features/definitions.ts b/extensions/typescript-language-features/src/features/definitions.ts index 5fe72c2005f59..fd3a1f10e79e6 100644 --- a/extensions/typescript-language-features/src/features/definitions.ts +++ b/extensions/typescript-language-features/src/features/definitions.ts @@ -37,10 +37,18 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase return response.body.definitions .map((location): vscode.DefinitionLink => { const target = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location); + if ((location as any).contextStart) { + return { + originSelectionRange: span, + targetRange: typeConverters.Range.fromLocations((location as any).contextStart, (location as any).contextEnd), + targetUri: target.uri, + targetSelectionRange: target.range, + }; + } return { originSelectionRange: span, targetRange: target.range, - targetUri: target.uri, + targetUri: target.uri }; }); } diff --git a/extensions/typescript-language-features/src/utils/typeConverters.ts b/extensions/typescript-language-features/src/utils/typeConverters.ts index eaa6a96c860c3..37947b38810d5 100644 --- a/extensions/typescript-language-features/src/utils/typeConverters.ts +++ b/extensions/typescript-language-features/src/utils/typeConverters.ts @@ -13,9 +13,12 @@ import { ITypeScriptServiceClient } from '../typescriptService'; export namespace Range { export const fromTextSpan = (span: Proto.TextSpan): vscode.Range => + fromLocations(span.start, span.end); + + export const fromLocations = (start: Proto.Location, end: Proto.Location): vscode.Range => new vscode.Range( - Math.max(0, span.start.line - 1), Math.max(span.start.offset - 1, 0), - Math.max(0, span.end.line - 1), Math.max(0, span.end.offset - 1)); + Math.max(0, start.line - 1), Math.max(start.offset - 1, 0), + Math.max(0, end.line - 1), Math.max(0, end.offset - 1)); export const toFileRangeRequestArgs = (file: string, range: vscode.Range): Proto.FileRangeRequestArgs => ({ file, diff --git a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts index 7c81a73fb159d..5c81fdeae5744 100644 --- a/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts +++ b/src/vs/editor/contrib/goToDefinition/goToDefinitionMouse.ts @@ -10,7 +10,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { IModeService } from 'vs/editor/common/services/modeService'; -import { Range } from 'vs/editor/common/core/range'; +import { Range, IRange } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { DefinitionProviderRegistry, LocationLink } from 'vs/editor/common/modes'; import { ICodeEditor, IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser'; @@ -150,7 +150,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC return; } - const previewValue = this.getPreviewValue(textEditorModel, startLineNumber); + const previewValue = this.getPreviewValue(textEditorModel, startLineNumber, result); let wordRange: Range; if (result.originSelectionRange) { @@ -170,8 +170,8 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC }).then(undefined, onUnexpectedError); } - private getPreviewValue(textEditorModel: ITextModel, startLineNumber: number) { - let rangeToUse = this.getPreviewRangeBasedOnBrackets(textEditorModel, startLineNumber); + private getPreviewValue(textEditorModel: ITextModel, startLineNumber: number, result: LocationLink) { + let rangeToUse = result.targetSelectionRange ? result.range : this.getPreviewRangeBasedOnBrackets(textEditorModel, startLineNumber); const numberOfLinesInRange = rangeToUse.endLineNumber - rangeToUse.startLineNumber; if (numberOfLinesInRange >= GotoDefinitionWithMouseEditorContribution.MAX_SOURCE_PREVIEW_LINES) { rangeToUse = this.getPreviewRangeBasedOnIndentation(textEditorModel, startLineNumber); @@ -181,7 +181,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC return previewValue; } - private stripIndentationFromPreviewRange(textEditorModel: ITextModel, startLineNumber: number, previewRange: Range) { + private stripIndentationFromPreviewRange(textEditorModel: ITextModel, startLineNumber: number, previewRange: IRange) { const startIndent = textEditorModel.getLineFirstNonWhitespaceColumn(startLineNumber); let minIndent = startIndent; From 3f3e0a53eba227a10c18d7c2950569af9b79518e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 18 Jun 2019 10:13:04 +0200 Subject: [PATCH 025/364] tree: active indent guides highlighting --- src/vs/base/browser/dom.ts | 28 ++++---- src/vs/base/browser/ui/tree/abstractTree.ts | 73 ++++++++++++++++++--- src/vs/base/browser/ui/tree/media/tree.css | 2 +- src/vs/base/common/collections.ts | 40 +++++++++++ 4 files changed, 120 insertions(+), 23 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 8aad714eb99c7..64fd5661495bb 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -38,12 +38,12 @@ export function isInDOM(node: Node | null): boolean { } interface IDomClassList { - hasClass(node: HTMLElement, className: string): boolean; - addClass(node: HTMLElement, className: string): void; - addClasses(node: HTMLElement, ...classNames: string[]): void; - removeClass(node: HTMLElement, className: string): void; - removeClasses(node: HTMLElement, ...classNames: string[]): void; - toggleClass(node: HTMLElement, className: string, shouldHaveIt?: boolean): void; + hasClass(node: HTMLElement | SVGElement, className: string): boolean; + addClass(node: HTMLElement | SVGElement, className: string): void; + addClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void; + removeClass(node: HTMLElement | SVGElement, className: string): void; + removeClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void; + toggleClass(node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean): void; } const _manualClassList = new class implements IDomClassList { @@ -191,12 +191,12 @@ const _nativeClassList = new class implements IDomClassList { // In IE11 there is only partial support for `classList` which makes us keep our // custom implementation. Otherwise use the native implementation, see: http://caniuse.com/#search=classlist const _classList: IDomClassList = browser.isIE ? _manualClassList : _nativeClassList; -export const hasClass: (node: HTMLElement, className: string) => boolean = _classList.hasClass.bind(_classList); -export const addClass: (node: HTMLElement, className: string) => void = _classList.addClass.bind(_classList); -export const addClasses: (node: HTMLElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList); -export const removeClass: (node: HTMLElement, className: string) => void = _classList.removeClass.bind(_classList); -export const removeClasses: (node: HTMLElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList); -export const toggleClass: (node: HTMLElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList); +export const hasClass: (node: HTMLElement | SVGElement, className: string) => boolean = _classList.hasClass.bind(_classList); +export const addClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.addClass.bind(_classList); +export const addClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList); +export const removeClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.removeClass.bind(_classList); +export const removeClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList); +export const toggleClass: (node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList); class DomListener implements IDisposable { @@ -992,7 +992,7 @@ export enum Namespace { SVG = 'http://www.w3.org/2000/svg' } -function _$(namespace: Namespace, description: string, attrs?: { [key: string]: any; }, ...children: Array): T { +function _$(namespace: Namespace, description: string, attrs?: { [key: string]: any; }, ...children: Array): T { let match = SELECTOR_REGEX.exec(description); if (!match) { @@ -1047,7 +1047,7 @@ export function $(description: string, attrs?: { [key: st return _$(Namespace.HTML, description, attrs, ...children); } -$.SVG = (description: string, attrs?: { [key: string]: any; }, ...children: Array) => { +$.SVG = function (description: string, attrs?: { [key: string]: any; }, ...children: Array): T { return _$(Namespace.SVG, description, attrs, ...children); }; diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index b9a7d25da9fd8..1ce6b054c2cf7 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/tree'; -import { IDisposable, dispose, Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IListOptions, List, IListStyles, mightProducePrintableCharacter, MouseController } from 'vs/base/browser/ui/list/listWidget'; import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list'; import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom'; @@ -25,6 +25,7 @@ import { isMacintosh } from 'vs/base/common/platform'; import { values } from 'vs/base/common/map'; import { clamp } from 'vs/base/common/numbers'; import { ScrollEvent } from 'vs/base/common/scrollable'; +import { SetMap } from 'vs/base/common/collections'; function asTreeDragAndDropData(data: IDragAndDropData): IDragAndDropData { if (data instanceof ElementsDragAndDropData) { @@ -190,6 +191,7 @@ interface ITreeListTemplateData { readonly container: HTMLElement; readonly indent: HTMLElement; readonly twistie: HTMLElement; + indentGuidesDisposable: IDisposable; readonly templateData: T; } @@ -210,11 +212,14 @@ class TreeRenderer implements IListRenderer>(); private renderedNodes = new Map, IRenderData>(); private indent: number = TreeRenderer.DefaultIndent; + private renderedIndentGuides = new SetMap, SVGLineElement>(); + private activeParentNodes = new Set>(); private disposables: IDisposable[] = []; constructor( private renderer: ITreeRenderer, onDidChangeCollapseState: Event>, + onDidChangeActiveNodes: Event[]>, options: ITreeRendererOptions = {} ) { this.templateId = renderer.templateId; @@ -225,6 +230,8 @@ class TreeRenderer implements IListRenderer implements IListRenderer, index: number, templateData: ITreeListTemplateData, height: number | undefined): void { @@ -263,6 +270,8 @@ class TreeRenderer implements IListRenderer, index: number, templateData: ITreeListTemplateData, height: number | undefined): void { + templateData.indentGuidesDisposable.dispose(); + if (this.renderer.disposeElement) { this.renderer.disposeElement(node, index, templateData.templateData, height); } @@ -314,18 +323,60 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { - const width = this.indent * node.depth; + private renderIndentGuides(target: ITreeNode, templateData: ITreeListTemplateData, height: number): void { + templateData.indentGuidesDisposable.dispose(); + + const disposableStore = new DisposableStore(); + const width = this.indent * target.depth; const svg = $.SVG('svg', { 'shape-rendering': 'crispEdges', width: `${width}`, height: `${height}`, viewBox: `0 0 ${width} ${height}` }); - for (let i = 1; i < node.depth; i++) { - const x = Math.floor((node.depth - i - 1) * this.indent) + 6; - const line = $.SVG('line', { x1: x, y1: 0, x2: x, y2: height }); + let node = target; + let i = 1; + + while (node.parent && node.parent.parent) { + const parent = node.parent; + const x = Math.floor((target.depth - i - 1) * this.indent) + 6; + const line = $.SVG('line', { x1: x, y1: 0, x2: x, y2: height }); + + if (this.activeParentNodes.has(parent)) { + addClass(line, 'active'); + } + svg.appendChild(line); + + this.renderedIndentGuides.add(parent, line); + disposableStore.add(toDisposable(() => this.renderedIndentGuides.delete(parent, line))); + + node = parent; + i++; } clearNode(templateData.indent); templateData.indent.appendChild(svg); + templateData.indentGuidesDisposable = disposableStore; + } + + private onDidChangeActiveNodes(nodes: ITreeNode[]): void { + const set = new Set>(); + nodes.forEach(node => { + if (node.parent) { + set.add(node.parent); + } + }); + + this.activeParentNodes.forEach(node => { + if (!set.has(node)) { + this.renderedIndentGuides.forEach(node, line => removeClass(line, 'active')); + } + }); + + set.forEach(node => { + if (!this.activeParentNodes.has(node)) { + this.renderedIndentGuides.forEach(node, line => addClass(line, 'active')); + } + }); + + this.activeParentNodes = set; } dispose(): void { @@ -845,6 +896,10 @@ class Trait { return [...this.elements]; } + getNodes(): readonly ITreeNode[] { + return this.nodes; + } + has(node: ITreeNode): boolean { return this.nodeSet.has(node); } @@ -1079,7 +1134,8 @@ export abstract class AbstractTree implements IDisposable const treeDelegate = new ComposedTreeDelegate>(delegate); const onDidChangeCollapseStateRelay = new Relay>(); - this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, _options)); + const onDidChangeActiveNodes = new Relay[]>(); + this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, onDidChangeActiveNodes.event, _options)); this.disposables.push(...this.renderers); let filter: TypeFilter | undefined; @@ -1092,6 +1148,7 @@ export abstract class AbstractTree implements IDisposable this.focus = new Trait(_options.identityProvider); this.selection = new Trait(_options.identityProvider); + onDidChangeActiveNodes.input = Event.map(Event.any(this.focus.onDidChange, this.selection.onDidChange), () => [...this.focus.getNodes(), ...this.selection.getNodes()]); this.view = new TreeNodeList(container, treeDelegate, this.renderers, this.focus, this.selection, { ...asListOptions(() => this.model, _options), tree: this }); this.model = this.createModel(this.view, _options); diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index f19695f2fcbf0..b538dd6488333 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -82,5 +82,5 @@ .monaco-list .monaco-tl-indent > svg > line { stroke: transparent; - transition: stroke 0.15s linear; + transition: stroke 0.1s linear; } \ No newline at end of file diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index f5c5cf5408bcf..d0c3e84ece397 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -96,4 +96,44 @@ export function fromMap(original: Map): IStringDictionary { }); } return result; +} + +export class SetMap { + + private map = new Map>(); + + add(key: K, value: V): void { + let values = this.map.get(key); + + if (!values) { + values = new Set(); + this.map.set(key, values); + } + + values.add(value); + } + + delete(key: K, value: V): void { + const values = this.map.get(key); + + if (!values) { + return; + } + + values.delete(value); + + if (values.size === 0) { + this.map.delete(key); + } + } + + forEach(key: K, fn: (value: V) => void): void { + const values = this.map.get(key); + + if (!values) { + return; + } + + values.forEach(fn); + } } \ No newline at end of file From c516a4f26f2a7732ed5595bbfbf32d34e460dde1 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 18 Jun 2019 12:07:11 +0200 Subject: [PATCH 026/364] fix indent guides on refresh --- src/vs/base/browser/ui/tree/abstractTree.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 1ce6b054c2cf7..5e1c71d3d8d49 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -358,6 +358,7 @@ class TreeRenderer implements IListRenderer[]): void { const set = new Set>(); + nodes.forEach(node => { if (node.parent) { set.add(node.parent); @@ -1148,7 +1149,6 @@ export abstract class AbstractTree implements IDisposable this.focus = new Trait(_options.identityProvider); this.selection = new Trait(_options.identityProvider); - onDidChangeActiveNodes.input = Event.map(Event.any(this.focus.onDidChange, this.selection.onDidChange), () => [...this.focus.getNodes(), ...this.selection.getNodes()]); this.view = new TreeNodeList(container, treeDelegate, this.renderers, this.focus, this.selection, { ...asListOptions(() => this.model, _options), tree: this }); this.model = this.createModel(this.view, _options); @@ -1159,6 +1159,8 @@ export abstract class AbstractTree implements IDisposable this.selection.onDidModelSplice(e); }, null, this.disposables); + onDidChangeActiveNodes.input = Event.map(Event.any(this.focus.onDidChange, this.selection.onDidChange, this.model.onDidSplice), () => [...this.focus.getNodes(), ...this.selection.getNodes()]); + if (_options.keyboardSupport !== false) { const onKeyDown = Event.chain(this.view.onKeyDown) .filter(e => !isInputElement(e.target as HTMLElement)) From b075690c38e06c9550a866f349e62268cd010590 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 18 Jun 2019 12:30:00 +0200 Subject: [PATCH 027/364] setting: workbench.tree.renderIndentGuides --- src/vs/base/browser/ui/tree/abstractTree.ts | 65 +++++++++++++++++++-- src/vs/platform/list/browser/listService.ts | 11 ++++ 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 5e1c71d3d8d49..fafaa5a07219d 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -197,6 +197,7 @@ interface ITreeListTemplateData { interface ITreeRendererOptions { readonly indent?: number; + readonly renderIndentGuides?: boolean; } interface IRenderData { @@ -204,6 +205,28 @@ interface IRenderData { height: number; } +interface Collection { + readonly elements: T[]; + readonly onDidChange: Event; +} + +class EventCollection implements Collection { + + private disposables = new DisposableStore(); + + get elements(): T[] { + return this._elements; + } + + constructor(readonly onDidChange: Event, private _elements: T[] = []) { + onDidChange(e => this._elements = e, null, this.disposables); + } + + dispose() { + this.disposables.dispose(); + } +} + class TreeRenderer implements IListRenderer, ITreeListTemplateData> { private static DefaultIndent = 8; @@ -212,14 +235,18 @@ class TreeRenderer implements IListRenderer>(); private renderedNodes = new Map, IRenderData>(); private indent: number = TreeRenderer.DefaultIndent; + + private _renderIndentGuides = false; private renderedIndentGuides = new SetMap, SVGLineElement>(); private activeParentNodes = new Set>(); + private indentGuidesDisposable: IDisposable = Disposable.None; + private disposables: IDisposable[] = []; constructor( private renderer: ITreeRenderer, onDidChangeCollapseState: Event>, - onDidChangeActiveNodes: Event[]>, + private activeNodes: Collection>, options: ITreeRendererOptions = {} ) { this.templateId = renderer.templateId; @@ -230,14 +257,28 @@ class TreeRenderer implements IListRenderer { @@ -322,8 +363,12 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { + if (!this._renderIndentGuides) { + clearNode(templateData.indent); + return; + } + templateData.indentGuidesDisposable.dispose(); const disposableStore = new DisposableStore(); @@ -356,7 +401,11 @@ class TreeRenderer implements IListRenderer[]): void { + private _onDidChangeActiveNodes(nodes: ITreeNode[]): void { + if (!this._renderIndentGuides) { + return; + } + const set = new Set>(); nodes.forEach(node => { @@ -383,6 +432,7 @@ class TreeRenderer implements IListRenderer implements IDisposable const onDidChangeCollapseStateRelay = new Relay>(); const onDidChangeActiveNodes = new Relay[]>(); - this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, onDidChangeActiveNodes.event, _options)); + const activeNodes = new EventCollection(onDidChangeActiveNodes.event); + this.disposables.push(activeNodes); + + this.renderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event, activeNodes, _options)); this.disposables.push(...this.renderers); let filter: TypeFilter | undefined; diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 3017aeda73691..41c64f35cbdd7 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -114,6 +114,7 @@ export const horizontalScrollingKey = 'workbench.list.horizontalScrolling'; export const keyboardNavigationSettingKey = 'workbench.list.keyboardNavigation'; export const automaticKeyboardNavigationSettingKey = 'workbench.list.automaticKeyboardNavigation'; const treeIndentKey = 'workbench.tree.indent'; +const treeRenderIndentGuidesKey = 'workbench.tree.renderIndentGuides'; function getHorizontalScrollingSetting(configurationService: IConfigurationService): boolean { return getMigratedSettingValue(configurationService, horizontalScrollingKey, 'workbench.tree.horizontalScrolling'); @@ -897,6 +898,7 @@ function workbenchTreeDataPreamble( ...computeStyles(themeService.getTheme(), defaultListStyles), ...workbenchListOptions, indent: configurationService.getValue(treeIndentKey), + renderIndentGuides: configurationService.getValue(treeRenderIndentGuidesKey), automaticKeyboardNavigation: getAutomaticKeyboardNavigation(), simpleKeyboardNavigation: keyboardNavigation === 'simple', filterOnType: keyboardNavigation === 'filter', @@ -977,6 +979,10 @@ class WorkbenchTreeInternals { const indent = configurationService.getValue(treeIndentKey); tree.updateOptions({ indent }); } + if (e.affectsConfiguration(treeRenderIndentGuidesKey)) { + const renderIndentGuides = configurationService.getValue(treeRenderIndentGuidesKey); + tree.updateOptions({ renderIndentGuides }); + } if (e.affectsConfiguration(keyboardNavigationSettingKey)) { updateKeyboardNavigation(); } @@ -1053,6 +1059,11 @@ configurationRegistry.registerConfiguration({ maximum: 40, 'description': localize('tree indent setting', "Controls tree indentation in pixels.") }, + [treeRenderIndentGuidesKey]: { + type: 'boolean', + default: false, + 'description': localize('render tree indent guides', "Controls whether the tree should render indent guides.") + }, [keyboardNavigationSettingKey]: { 'type': 'string', 'enum': ['simple', 'highlight', 'filter'], From ac75421fc0296603d1ea97f966383778fafd2d3a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 18 Jun 2019 12:37:23 +0200 Subject: [PATCH 028/364] indent guides fix misalignment in explorer --- src/vs/base/browser/ui/tree/abstractTree.ts | 8 ++++++-- src/vs/base/browser/ui/tree/media/tree.css | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index fafaa5a07219d..e72b300d44e52 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -380,7 +380,7 @@ class TreeRenderer implements IListRenderer('line', { x1: x, y1: 0, x2: x, y2: height }); if (this.activeParentNodes.has(parent)) { @@ -397,7 +397,11 @@ class TreeRenderer implements IListRenderer Date: Tue, 18 Jun 2019 12:45:39 +0200 Subject: [PATCH 029/364] fix bad tree options update --- src/vs/base/browser/ui/tree/abstractTree.ts | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index e72b300d44e52..c110d9b29a904 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -264,19 +264,21 @@ class TreeRenderer implements IListRenderer Date: Tue, 18 Jun 2019 12:54:37 +0200 Subject: [PATCH 030/364] tree.renderIndentGuides always --- src/vs/base/browser/ui/tree/abstractTree.ts | 21 +++++++++++++++------ src/vs/platform/list/browser/listService.ts | 13 +++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index c110d9b29a904..829b7fb131c6b 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -195,9 +195,15 @@ interface ITreeListTemplateData { readonly templateData: T; } +export enum RenderIndentGuides { + None = 'none', + OnHover = 'onHover', + Always = 'always' +} + interface ITreeRendererOptions { readonly indent?: number; - readonly renderIndentGuides?: boolean; + readonly renderIndentGuides?: RenderIndentGuides; } interface IRenderData { @@ -236,7 +242,7 @@ class TreeRenderer implements IListRenderer, IRenderData>(); private indent: number = TreeRenderer.DefaultIndent; - private _renderIndentGuides = false; + private _renderIndentGuides: RenderIndentGuides = RenderIndentGuides.None; private renderedIndentGuides = new SetMap, SVGLineElement>(); private activeParentNodes = new Set>(); private indentGuidesDisposable: IDisposable = Disposable.None; @@ -265,7 +271,7 @@ class TreeRenderer implements IListRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { - if (!this._renderIndentGuides) { + if (this._renderIndentGuides === RenderIndentGuides.None) { clearNode(templateData.indent); return; } @@ -408,7 +414,7 @@ class TreeRenderer implements IListRenderer[]): void { - if (!this._renderIndentGuides) { + if (this._renderIndentGuides === RenderIndentGuides.None) { return; } @@ -1237,6 +1243,7 @@ export abstract class AbstractTree implements IDisposable } this.styleElement = createStyleSheet(this.view.getHTMLElement()); + toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always); } updateOptions(optionsUpdate: IAbstractTreeOptionsUpdate = {}): void { @@ -1256,6 +1263,8 @@ export abstract class AbstractTree implements IDisposable } this._onDidUpdateOptions.fire(this._options); + + toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always); } get options(): IAbstractTreeOptions { @@ -1341,7 +1350,7 @@ export abstract class AbstractTree implements IDisposable const content: string[] = []; if (styles.treeIndentGuidesStroke) { - content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`); + content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line, .monaco-list${suffix}.always .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`); content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); } diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 41c64f35cbdd7..8ee27a7c085b1 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -29,7 +29,7 @@ import { ObjectTree, IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTr import { ITreeEvent, ITreeRenderer, IAsyncDataSource, IDataSource, ITreeMouseEvent } from 'vs/base/browser/ui/tree/tree'; import { AsyncDataTree, IAsyncDataTreeOptions } from 'vs/base/browser/ui/tree/asyncDataTree'; import { DataTree, IDataTreeOptions } from 'vs/base/browser/ui/tree/dataTree'; -import { IKeyboardNavigationEventFilter, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree'; +import { IKeyboardNavigationEventFilter, IAbstractTreeOptions, RenderIndentGuides } from 'vs/base/browser/ui/tree/abstractTree'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; export type ListWidget = List | PagedList | ITree | ObjectTree | DataTree | AsyncDataTree; @@ -898,7 +898,7 @@ function workbenchTreeDataPreamble( ...computeStyles(themeService.getTheme(), defaultListStyles), ...workbenchListOptions, indent: configurationService.getValue(treeIndentKey), - renderIndentGuides: configurationService.getValue(treeRenderIndentGuidesKey), + renderIndentGuides: configurationService.getValue(treeRenderIndentGuidesKey), automaticKeyboardNavigation: getAutomaticKeyboardNavigation(), simpleKeyboardNavigation: keyboardNavigation === 'simple', filterOnType: keyboardNavigation === 'filter', @@ -980,7 +980,7 @@ class WorkbenchTreeInternals { tree.updateOptions({ indent }); } if (e.affectsConfiguration(treeRenderIndentGuidesKey)) { - const renderIndentGuides = configurationService.getValue(treeRenderIndentGuidesKey); + const renderIndentGuides = configurationService.getValue(treeRenderIndentGuidesKey); tree.updateOptions({ renderIndentGuides }); } if (e.affectsConfiguration(keyboardNavigationSettingKey)) { @@ -1060,9 +1060,10 @@ configurationRegistry.registerConfiguration({ 'description': localize('tree indent setting', "Controls tree indentation in pixels.") }, [treeRenderIndentGuidesKey]: { - type: 'boolean', - default: false, - 'description': localize('render tree indent guides', "Controls whether the tree should render indent guides.") + type: 'string', + enum: ['none', 'onHover', 'always'], + default: 'none', + description: localize('render tree indent guides', "Controls whether the tree should render indent guides.") }, [keyboardNavigationSettingKey]: { 'type': 'string', From 4b5960616720c1f6e5769b7976c829eca292a65b Mon Sep 17 00:00:00 2001 From: orange4glace Date: Tue, 18 Jun 2019 20:05:02 +0900 Subject: [PATCH 031/364] fix: #75693 --- .../files/browser/views/explorerViewer.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 76fab05327567..3da1ae98039bf 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -218,22 +218,20 @@ export class FilesRenderer implements ITreeRenderer inputBox.focus(), 100); inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); - const done = once(async (success: boolean, finishEditing: boolean) => { + const done = once(async (success: boolean) => { label.element.style.display = 'none'; const value = inputBox.value; dispose(toDispose); container.removeChild(label.element); - if (finishEditing) { - // Timeout: once done rendering only then re-render #70902 - setTimeout(() => editableData.onFinish(value, success), 0); - } + // Timeout: once done rendering only then re-render #70902 + setTimeout(() => editableData.onFinish(value, success), 0); }); const blurDisposable = DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => { - done(inputBox.isInputValid(), true); + done(inputBox.isInputValid()); }); const toDispose = [ @@ -241,10 +239,10 @@ export class FilesRenderer implements ITreeRenderer { if (e.equals(KeyCode.Enter)) { if (inputBox.validate()) { - done(true, true); + done(true); } } else if (e.equals(KeyCode.Escape)) { - done(false, true); + done(false); } }), blurDisposable, @@ -254,7 +252,7 @@ export class FilesRenderer implements ITreeRenderer { blurDisposable.dispose(); - done(false, false); + done(false); }); } From 985de26b3446636f86e2bb2b14dbeb9ec1e33207 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 18 Jun 2019 13:47:40 +0200 Subject: [PATCH 032/364] Add availableFileSystems to save as (#75681) This adds the suggested filename to the local path --- .../browser/actions/workspaceActions.ts | 14 +++++++++--- .../dialogs/browser/remoteFileDialog.ts | 22 +++++++++---------- .../textfile/common/textFileService.ts | 11 +++++----- .../services/textfile/common/textfiles.ts | 1 + 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 2c7298ebcdd69..68fe0859f5916 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -17,6 +17,9 @@ import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { Schemas } from 'vs/base/common/network'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { ITextFileService, ISaveOptions } from 'vs/workbench/services/textfile/common/textfiles'; +import { toResource } from 'vs/workbench/common/editor'; +import { URI } from 'vs/base/common/uri'; export class OpenFileAction extends Action { @@ -62,13 +65,18 @@ export class SaveLocalFileAction extends Action { constructor( id: string, label: string, - @IFileDialogService private readonly dialogService: IFileDialogService + @ITextFileService private readonly textFileService: ITextFileService, + @IEditorService private readonly editorService: IEditorService ) { super(id, label); } - run(event?: any, data?: ITelemetryData): Promise { - return this.dialogService.pickFileToSave({ availableFileSystems: [Schemas.file] }); + async run(event?: any, data?: ITelemetryData): Promise { + let resource: URI | undefined = toResource(this.editorService.activeEditor); + const options: ISaveOptions = { force: true, availableFileSystems: [Schemas.file] }; + if (resource) { + return this.textFileService.saveAs(resource, undefined, options); + } } } diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index 06ae69f7b9c6e..73aa2adcd4e91 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -98,7 +98,7 @@ export class RemoteFileDialog { } public async showOpenDialog(options: IOpenDialogOptions = {}): Promise { - this.scheme = this.getScheme(options.defaultUri, options.availableFileSystems); + this.scheme = this.getScheme(options.availableFileSystems); this.userHome = await this.getUserHome(); const newOptions = await this.getOptions(options); if (!newOptions) { @@ -109,7 +109,7 @@ export class RemoteFileDialog { } public async showSaveDialog(options: ISaveDialogOptions): Promise { - this.scheme = this.getScheme(options.defaultUri, options.availableFileSystems); + this.scheme = this.getScheme(options.availableFileSystems); this.userHome = await this.getUserHome(); this.requiresTrailing = true; const newOptions = await this.getOptions(options, true); @@ -128,9 +128,13 @@ export class RemoteFileDialog { } private getOptions(options: ISaveDialogOptions | IOpenDialogOptions, isSave: boolean = false): IOpenDialogOptions | undefined { - let defaultUri = options.defaultUri; - const filename = (defaultUri && isSave && (resources.dirname(defaultUri).path === '/')) ? resources.basename(defaultUri) : undefined; - if (!defaultUri || filename) { + let defaultUri: URI | undefined = undefined; + let filename: string | undefined = undefined; + if (options.defaultUri) { + defaultUri = (this.scheme === options.defaultUri.scheme) ? options.defaultUri : undefined; + filename = isSave ? resources.basename(options.defaultUri) : undefined; + } + if (!defaultUri) { defaultUri = this.userHome; if (filename) { defaultUri = resources.joinPath(defaultUri, filename); @@ -150,8 +154,8 @@ export class RemoteFileDialog { return resources.toLocalResource(URI.from({ scheme: this.scheme, path }), this.scheme === Schemas.file ? undefined : this.remoteAuthority); } - private getScheme(defaultUri: URI | undefined, available: string[] | undefined): string { - return defaultUri ? defaultUri.scheme : (available ? available[0] : Schemas.file); + private getScheme(available: string[] | undefined): string { + return available ? available[0] : Schemas.file; } private async getRemoteAgentEnvironment(): Promise { @@ -254,12 +258,8 @@ export class RemoteFileDialog { if (this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) { this.options.availableFileSystems.shift(); } - this.options.defaultUri = undefined; this.filePickBox.hide(); if (isSave) { - // Remove defaultUri and filters to get a consistant experience with the keybinding. - this.options.defaultUri = undefined; - this.options.filters = undefined; return this.fileDialogService.showSaveDialog(this.options).then(result => { doResolve(this, result); }); diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index 4c092ee588bb1..b5e8392641979 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -648,18 +648,19 @@ export abstract class TextFileService extends Disposable implements ITextFileSer return result; } - protected async promptForPath(resource: URI, defaultUri: URI): Promise { + protected async promptForPath(resource: URI, defaultUri: URI, availableFileSystems?: string[]): Promise { // Help user to find a name for the file by opening it first await this.editorService.openEditor({ resource, options: { revealIfOpened: true, preserveFocus: true, } }); - return this.fileDialogService.pickFileToSave(this.getSaveDialogOptions(defaultUri)); + return this.fileDialogService.pickFileToSave(this.getSaveDialogOptions(defaultUri, availableFileSystems)); } - private getSaveDialogOptions(defaultUri: URI): ISaveDialogOptions { + private getSaveDialogOptions(defaultUri: URI, availableFileSystems?: string[]): ISaveDialogOptions { const options: ISaveDialogOptions = { defaultUri, - title: nls.localize('saveAsTitle', "Save As") + title: nls.localize('saveAsTitle', "Save As"), + availableFileSystems, }; // Filters are only enabled on Windows where they work properly @@ -765,7 +766,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer dialogPath = this.suggestFileName(resource); } - targetResource = await this.promptForPath(resource, dialogPath); + targetResource = await this.promptForPath(resource, dialogPath, options ? options.availableFileSystems : undefined); } if (!targetResource) { diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index d21782426076c..a83474a5806f1 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -428,6 +428,7 @@ export interface ISaveOptions { overwriteEncoding?: boolean; skipSaveParticipants?: boolean; writeElevated?: boolean; + availableFileSystems?: string[]; } export interface ILoadOptions { From 356440d72d7b93f61095eedea4ad4e20cef93a5e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 18 Jun 2019 13:48:26 +0200 Subject: [PATCH 033/364] windows - disable terminal integration tests (#75689) --- .../vscode-api-tests/src/singlefolder-tests/window.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts index 4218162c24d38..321e885acbb87 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts @@ -569,7 +569,7 @@ suite('window namespace tests', () => { }); }); - suite('Terminal', () => { + (process.platform === 'win32' ? suite.skip /* https://github.com/microsoft/vscode/issues/75689 */ : suite)('Terminal', () => { test('sendText immediately after createTerminal should not throw', () => { const terminal = window.createTerminal(); assert.doesNotThrow(terminal.sendText.bind(terminal, 'echo "foo"')); From 1b5ff0a2403fa959e67886e5746c5325bf0b623b Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 18 Jun 2019 14:57:05 +0200 Subject: [PATCH 034/364] tree indent guides: dynamic heights --- src/vs/base/browser/ui/tree/abstractTree.ts | 8 +++++++- src/vs/base/browser/ui/tree/media/tree.css | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 829b7fb131c6b..fadc69ed298d6 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -381,7 +381,13 @@ class TreeRenderer implements IListRenderer svg { + height: 100%; +} + .monaco-list .monaco-tl-indent > svg > line { stroke: transparent; transition: stroke 0.1s linear; From 4e7353aeb87b929702ea33ae7fd2bbfe1ff40c08 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 18 Jun 2019 14:57:14 +0200 Subject: [PATCH 035/364] tree indent: default onHover --- src/vs/platform/list/browser/listService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/list/browser/listService.ts b/src/vs/platform/list/browser/listService.ts index 8ee27a7c085b1..c885cca5e51a4 100644 --- a/src/vs/platform/list/browser/listService.ts +++ b/src/vs/platform/list/browser/listService.ts @@ -1062,7 +1062,7 @@ configurationRegistry.registerConfiguration({ [treeRenderIndentGuidesKey]: { type: 'string', enum: ['none', 'onHover', 'always'], - default: 'none', + default: 'onHover', description: localize('render tree indent guides', "Controls whether the tree should render indent guides.") }, [keyboardNavigationSettingKey]: { From 4118892ac517f7f37b6bc7747601c085038f1a17 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 18 Jun 2019 15:08:02 +0200 Subject: [PATCH 036/364] web - hot exit off by default for now until supported --- src/vs/workbench/contrib/files/browser/files.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index f76f558041ff1..88ad0027e9c98 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -311,7 +311,7 @@ configurationRegistry.registerConfiguration({ 'type': 'string', 'scope': ConfigurationScope.APPLICATION, 'enum': [HotExitConfiguration.OFF, HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE], - 'default': HotExitConfiguration.ON_EXIT, + 'default': platform.isWeb ? HotExitConfiguration.OFF : HotExitConfiguration.ON_EXIT, // TODO@Ben enable once supported 'markdownEnumDescriptions': [ nls.localize('hotExit.off', 'Disable hot exit.'), nls.localize('hotExit.onExit', 'Hot exit will be triggered when the last window is closed on Windows/Linux or when the `workbench.action.quit` command is triggered (command palette, keybinding, menu). All windows with backups will be restored upon next launch.'), From 998a65e2ca6a5d8933416c8cf0a261fe86edafa5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 18 Jun 2019 15:12:41 +0200 Subject: [PATCH 037/364] web - best lifecycle support we can do currently --- .../lifecycle/browser/lifecycleService.ts | 58 +++++++++++++++++++ .../lifecycle/common/lifecycleService.ts | 3 +- .../electron-browser/lifecycleService.ts | 5 +- .../lifecycle/electron-main/lifecycleMain.ts | 2 +- .../api/browser/mainThreadWebview.ts | 6 +- .../workbench/browser/web.simpleservices.ts | 54 +---------------- .../textfile/browser/textFileService.ts | 14 +++++ .../textfile/common/textFileService.ts | 2 +- .../workspaceEditingService.ts | 6 +- src/vs/workbench/workbench.web.main.ts | 8 +-- 10 files changed, 91 insertions(+), 67 deletions(-) create mode 100644 src/vs/platform/lifecycle/browser/lifecycleService.ts diff --git a/src/vs/platform/lifecycle/browser/lifecycleService.ts b/src/vs/platform/lifecycle/browser/lifecycleService.ts new file mode 100644 index 0000000000000..b0c3014986f3d --- /dev/null +++ b/src/vs/platform/lifecycle/browser/lifecycleService.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ShutdownReason, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { ILogService } from 'vs/platform/log/common/log'; +import { AbstractLifecycleService } from 'vs/platform/lifecycle/common/lifecycleService'; +import { localize } from 'vs/nls'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; + +export class BrowserLifecycleService extends AbstractLifecycleService { + + _serviceBrand: ServiceIdentifier; + + constructor( + @ILogService readonly logService: ILogService + ) { + super(logService); + + this.registerListeners(); + } + + private registerListeners(): void { + window.onbeforeunload = () => this.beforeUnload(); + } + + private beforeUnload(): string | null { + let veto: boolean = false; + + // Before Shutdown + this._onBeforeShutdown.fire({ + veto(value) { + if (value === true) { + veto = true; + } else if (value instanceof Promise && !veto) { + console.warn(new Error('Long running onBeforeShutdown currently not supported')); + } + }, + reason: ShutdownReason.QUIT + }); + + // Veto: signal back to browser by returning a non-falsify return value + if (veto) { + return localize('lifecycleVeto', "Changes that you made may not be saved. Please check press 'Cancel' and try again."); + } + + // No Veto: continue with Will Shutdown + this._onWillShutdown.fire({ + join() { + console.warn(new Error('Long running onWillShutdown currently not supported')); + }, + reason: ShutdownReason.QUIT + }); + + return null; + } +} \ No newline at end of file diff --git a/src/vs/platform/lifecycle/common/lifecycleService.ts b/src/vs/platform/lifecycle/common/lifecycleService.ts index a82dd63da4173..b325cde418a94 100644 --- a/src/vs/platform/lifecycle/common/lifecycleService.ts +++ b/src/vs/platform/lifecycle/common/lifecycleService.ts @@ -9,10 +9,11 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { ILifecycleService, BeforeShutdownEvent, WillShutdownEvent, StartupKind, LifecyclePhase, LifecyclePhaseToString } from 'vs/platform/lifecycle/common/lifecycle'; import { ILogService } from 'vs/platform/log/common/log'; import { mark } from 'vs/base/common/performance'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export abstract class AbstractLifecycleService extends Disposable implements ILifecycleService { - _serviceBrand: any; + _serviceBrand: ServiceIdentifier; protected readonly _onBeforeShutdown = this._register(new Emitter()); get onBeforeShutdown(): Event { return this._onBeforeShutdown.event; } diff --git a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts index aa7f6442e0804..ecef5c0277201 100644 --- a/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts +++ b/src/vs/platform/lifecycle/electron-browser/lifecycleService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { toErrorMessage } from 'vs/base/common/errorMessage'; -import { ShutdownReason, StartupKind, handleVetos } from 'vs/platform/lifecycle/common/lifecycle'; +import { ShutdownReason, StartupKind, handleVetos, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ipcRenderer as ipc } from 'electron'; import { IWindowService } from 'vs/platform/windows/common/windows'; @@ -12,12 +12,13 @@ import { ILogService } from 'vs/platform/log/common/log'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { onUnexpectedError } from 'vs/base/common/errors'; import { AbstractLifecycleService } from 'vs/platform/lifecycle/common/lifecycleService'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; export class LifecycleService extends AbstractLifecycleService { private static readonly LAST_SHUTDOWN_REASON_KEY = 'lifecyle.lastShutdownReason'; - _serviceBrand: any; + _serviceBrand: ServiceIdentifier; private shutdownReason: ShutdownReason; diff --git a/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts b/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts index a56ee98dec6cd..058efdc2500f5 100644 --- a/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts +++ b/src/vs/platform/lifecycle/electron-main/lifecycleMain.ts @@ -131,7 +131,7 @@ export const enum LifecycleMainPhase { export class LifecycleService extends Disposable implements ILifecycleService { - _serviceBrand: any; + _serviceBrand: ServiceIdentifier; private static readonly QUIT_FROM_RESTART_MARKER = 'quit.from.restart'; // use a marker to find out if the session was restarted diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index f41c0327ae351..83b6403e4f582 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -75,7 +75,8 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews })); this._register(lifecycleService.onBeforeShutdown(e => { - e.veto(this._onBeforeShutdown()); + this._onBeforeShutdown(); + e.veto(false); // Don't veto shutdown }, this)); } @@ -217,13 +218,12 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews return `mainThreadWebview-${viewType}`; } - private _onBeforeShutdown(): boolean { + private _onBeforeShutdown(): void { this._webviews.forEach((webview) => { if (!webview.isDisposed() && webview.state && this._revivers.has(webview.state.viewType)) { webview.state.state = webview.webviewState; } }); - return false; // Don't veto shutdown } private createWebviewEventDelegate(handle: WebviewPanelHandle) { diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 3654c72f7ae69..090913805ad4b 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -21,9 +21,8 @@ import { IPager } from 'vs/base/common/paging'; import { IExtensionManifest, ExtensionType, ExtensionIdentifier, IExtension } from 'vs/platform/extensions/common/extensions'; import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { ITelemetryService, ITelemetryData, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; -import { AbstractLifecycleService } from 'vs/platform/lifecycle/common/lifecycleService'; -import { ILogService, LogLevel, ConsoleLogService } from 'vs/platform/log/common/log'; -import { ShutdownReason, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { LogLevel, ConsoleLogService } from 'vs/platform/log/common/log'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IProductService } from 'vs/platform/product/common/product'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IStorageService, IWorkspaceStorageChangeEvent, StorageScope, IWillSaveStateEvent, WillSaveStateReason } from 'vs/platform/storage/common/storage'; @@ -518,55 +517,6 @@ registerSingleton(IExtensionUrlHandler, SimpleExtensionURLHandler, true); //#endregion -//#region Lifecycle - -export class SimpleLifecycleService extends AbstractLifecycleService { - - _serviceBrand: any; - - constructor( - @ILogService readonly logService: ILogService - ) { - super(logService); - - this.registerListeners(); - } - - private registerListeners(): void { - window.onbeforeunload = () => this.beforeUnload(); - } - - private beforeUnload(): string { - - // Before Shutdown - this._onBeforeShutdown.fire({ - veto(value) { - if (value === true) { - console.warn(new Error('Preventing onBeforeUnload currently not supported')); - } else if (value instanceof Promise) { - console.warn(new Error('Long running onBeforeShutdown currently not supported')); - } - }, - reason: ShutdownReason.QUIT - }); - - // Will Shutdown - this._onWillShutdown.fire({ - join() { - console.warn(new Error('Long running onWillShutdown currently not supported')); - }, - reason: ShutdownReason.QUIT - }); - - // @ts-ignore - return null; - } -} - -registerSingleton(ILifecycleService, SimpleLifecycleService); - -//#endregion - //#region Log export class SimpleLogService extends ConsoleLogService { } diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index d15549e21ccf9..8d6531651192e 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -6,6 +6,7 @@ import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService'; import { ITextFileService, IResourceEncodings, IResourceEncoding } from 'vs/workbench/services/textfile/common/textfiles'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ShutdownReason } from 'vs/platform/lifecycle/common/lifecycle'; export class BrowserTextFileService extends TextFileService { @@ -14,6 +15,19 @@ export class BrowserTextFileService extends TextFileService { return { encoding: 'utf8', hasBOM: false }; } }; + + protected beforeShutdown(reason: ShutdownReason): boolean | Promise { + const veto = super.beforeShutdown(reason); + + // Web: there is no support for long running unload handlers. As such + // we need to return a direct boolean veto when we detect that there + // are dirty files around. + if (veto instanceof Promise) { + return this.getDirty().length > 0; + } + + return veto; + } } registerSingleton(ITextFileService, BrowserTextFileService); \ No newline at end of file diff --git a/src/vs/workbench/services/textfile/common/textFileService.ts b/src/vs/workbench/services/textfile/common/textFileService.ts index b5e8392641979..83e8d9403055f 100644 --- a/src/vs/workbench/services/textfile/common/textFileService.ts +++ b/src/vs/workbench/services/textfile/common/textFileService.ts @@ -119,7 +119,7 @@ export abstract class TextFileService extends Disposable implements ITextFileSer })); } - private beforeShutdown(reason: ShutdownReason): boolean | Promise { + protected beforeShutdown(reason: ShutdownReason): boolean | Promise { // Dirty files need treatment on shutdown const dirty = this.getDirty(); diff --git a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts index d0c60e71c6a6c..905d2a8b29227 100644 --- a/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspace/electron-browser/workspaceEditingService.ts @@ -57,14 +57,16 @@ export class WorkspaceEditingService implements IWorkspaceEditingService { @ILifecycleService readonly lifecycleService: ILifecycleService, @ILabelService readonly labelService: ILabelService ) { + this.registerListeners(); + } - lifecycleService.onBeforeShutdown(async e => { + private registerListeners(): void { + this.lifecycleService.onBeforeShutdown(async e => { const saveOperation = this.saveUntitedBeforeShutdown(e.reason); if (saveOperation) { e.veto(saveOperation); } }); - } private async saveUntitedBeforeShutdown(reason: ShutdownReason): Promise { diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 3b2f85ac6a35e..e207ca87c0920 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -68,8 +68,8 @@ import { ContextViewService } from 'vs/platform/contextview/browser/contextViewS // import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; // import { IRequestService } from 'vs/platform/request/node/request'; // import { RequestService } from 'vs/platform/request/electron-browser/requestService'; -// import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; -// import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { BrowserLifecycleService } from 'vs/platform/lifecycle/browser/lifecycleService'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; // import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; // import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; // import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; @@ -152,7 +152,7 @@ registerSingleton(IAccessibilityService, BrowserAccessibilityService, true); registerSingleton(IContextViewService, ContextViewService, true); // registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); // registerSingleton(IRequestService, RequestService, true); -// registerSingleton(ILifecycleService, LifecycleService); +registerSingleton(ILifecycleService, BrowserLifecycleService); // registerSingleton(ILocalizationsService, LocalizationsService); // registerSingleton(ISharedProcessService, SharedProcessService, true); // registerSingleton(IProductService, ProductService, true); @@ -238,7 +238,6 @@ import 'vs/workbench/contrib/debug/browser/repl'; import 'vs/workbench/contrib/debug/browser/debugViewlet'; import 'vs/workbench/contrib/debug/browser/debugHelperService'; - // Markers import 'vs/workbench/contrib/markers/browser/markers.contribution'; @@ -288,7 +287,6 @@ import { TaskService } from 'vs/workbench/contrib/tasks/browser/taskService'; import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; registerSingleton(ITaskService, TaskService, true); - // Remote import 'vs/workbench/contrib/remote/common/remote.contribution'; // import 'vs/workbench/contrib/remote/electron-browser/remote.contribution'; From 23465510aefe30fbb9e3aa92f0892512bb1e2e75 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 18 Jun 2019 15:30:07 +0200 Subject: [PATCH 038/364] fix tests --- src/vs/workbench/test/workbenchTestServices.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index c33ab89e631c9..1342aa1944226 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -82,7 +82,7 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/node/environmentService'; import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; -import { BrowserTextFileService } from 'vs/workbench/services/textfile/browser/textFileService'; +import { NodeTextFileService } from 'vs/workbench/services/textfile/node/textFileService'; import { Schemas } from 'vs/base/common/network'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { @@ -177,7 +177,7 @@ export class TestContextService implements IWorkspaceContextService { } } -export class TestTextFileService extends BrowserTextFileService { +export class TestTextFileService extends NodeTextFileService { public cleanupBackupsBeforeShutdownCalled: boolean; private promptPath: URI; From ad41bd267412bf9823efbd8fc997cfb48ae89c1b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 18 Jun 2019 16:01:39 +0200 Subject: [PATCH 039/364] web - introduce browser environment service Hello first commit from browser :) --- src/vs/code/browser/workbench/workbench.html | 2 +- src/vs/code/browser/workbench/workbench.js | 2 +- src/vs/platform/sign/browser/signService.ts | 2 +- src/vs/workbench/browser/web.main.ts | 40 +----- .../workbench/browser/web.simpleservices.ts | 108 +------------- .../environment/browser/environmentService.ts | 136 ++++++++++++++++++ .../environment/common/environmentService.ts | 5 +- .../remote/browser/remoteAgentServiceImpl.ts | 8 +- tslint.json | 1 + 9 files changed, 155 insertions(+), 149 deletions(-) create mode 100644 src/vs/workbench/services/environment/browser/environmentService.ts diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 316826eea6723..679b872a315c9 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -15,7 +15,7 @@ ${this.getStyles(sourceUri, nonce, config, state)} - + ${body} @@ -108,8 +110,7 @@ export class MarkdownContentProvider { } private extensionResourcePath(mediaFile: string): string { - return vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile))) - .with({ scheme: 'vscode-resource' }) + return toResoruceUri(vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile)))) .toString(); } @@ -124,23 +125,17 @@ export class MarkdownContentProvider { // Assume it must be a local file if (path.isAbsolute(href)) { - return vscode.Uri.file(href) - .with({ scheme: 'vscode-resource' }) - .toString(); + return toResoruceUri(vscode.Uri.file(href)).toString(); } // Use a workspace relative path if there is a workspace const root = vscode.workspace.getWorkspaceFolder(resource); if (root) { - return vscode.Uri.file(path.join(root.uri.fsPath, href)) - .with({ scheme: 'vscode-resource' }) - .toString(); + return toResoruceUri(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString(); } // Otherwise look relative to the markdown file - return vscode.Uri.file(path.join(path.dirname(resource.fsPath), href)) - .with({ scheme: 'vscode-resource' }) - .toString(); + return toResoruceUri(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString(); } private computeCustomStyleSheetIncludes(resource: vscode.Uri, config: MarkdownPreviewConfiguration): string { @@ -197,17 +192,17 @@ export class MarkdownContentProvider { private getCspForResource(resource: vscode.Uri, nonce: string): string { switch (this.cspArbiter.getSecurityLevelForResource(resource)) { case MarkdownPreviewSecurityLevel.AllowInsecureContent: - return ``; + return ``; case MarkdownPreviewSecurityLevel.AllowInsecureLocalContent: - return ``; + return ``; case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent: return ''; case MarkdownPreviewSecurityLevel.Strict: default: - return ``; + return ``; } } } diff --git a/extensions/markdown-language-features/src/markdownExtensions.ts b/extensions/markdown-language-features/src/markdownExtensions.ts index 65899874f5a91..ffbdc3054b847 100644 --- a/extensions/markdown-language-features/src/markdownExtensions.ts +++ b/extensions/markdown-language-features/src/markdownExtensions.ts @@ -7,10 +7,10 @@ import * as vscode from 'vscode'; import * as path from 'path'; import { Disposable } from './util/dispose'; import * as arrays from './util/arrays'; +import { toResoruceUri } from './util/resources'; const resolveExtensionResource = (extension: vscode.Extension, resourcePath: string): vscode.Uri => { - return vscode.Uri.file(path.join(extension.extensionPath, resourcePath)) - .with({ scheme: 'vscode-resource' }); + return toResoruceUri(vscode.Uri.file(path.join(extension.extensionPath, resourcePath))); }; const resolveExtensionResources = (extension: vscode.Extension, resourcePaths: unknown): vscode.Uri[] => { diff --git a/extensions/markdown-language-features/src/util/resources.ts b/extensions/markdown-language-features/src/util/resources.ts new file mode 100644 index 0000000000000..f7133f5a0c41d --- /dev/null +++ b/extensions/markdown-language-features/src/util/resources.ts @@ -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. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; + +const rootUri = vscode.Uri.parse(vscode.env.webviewResourceRoot); + +export function toResoruceUri(uri: vscode.Uri): vscode.Uri { + return rootUri.with({ + path: rootUri.path + uri.path, + query: uri.query, + fragment: uri.fragment, + }); +} diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts index 3cc1cb3863b58..01e8b460efa6a 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts @@ -251,7 +251,7 @@ suite('Webview tests', () => { }); `); - const workspaceRootUri = vscode.Uri.file(vscode.workspace.rootPath!).with({ scheme: 'vscode-resource' }); + const workspaceRootUri = vscode.env.webviewResourceRoot + vscode.Uri.file(vscode.workspace.rootPath!).path; { const imagePath = workspaceRootUri.toString() + '/image.png'; diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index b2d41431207f8..1555f4f9dd5b9 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -153,4 +153,5 @@ export interface IEnvironmentService { driverVerbose: boolean; webviewEndpoint?: string; + readonly webviewResourceRoot: string; } diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index b4f9e1c2061e2..63f75996133de 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -266,6 +266,10 @@ export class EnvironmentService implements IEnvironmentService { get driverHandle(): string | undefined { return this._args['driver']; } get driverVerbose(): boolean { return !!this._args['driver-verbose']; } + get webviewResourceRoot(): string { + return 'vscode-resource:'; + } + constructor(private _args: ParsedArgs, private _execPath: string) { if (!process.env['VSCODE_LOGS']) { const key = toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, ''); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 13e1da3d9dcaa..16e52984ff999 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1464,4 +1464,18 @@ declare module 'vscode' { } //#endregion + + //#region Webview Resource Roots + + export namespace env { + /** + * Root url from which local resources are loaded inside of webviews. + * + * This is `vscode-resource:` when vscode is run on the desktop. When vscode is run + * on the web, this points to a server endpoint. + */ + export const webviewResourceRoot: string; + } + + //#endregion } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index bcd55cea583b8..2ce482060beff 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -58,6 +58,7 @@ export interface IEnvironment { extensionTestsLocationURI?: URI; globalStorageHome: URI; userHome: URI; + webviewResourceRoot: string; } export interface IStaticWorkspaceData { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index e86d15a475121..9b23ac7027e37 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -259,7 +259,11 @@ export function createApiFactory( }, openExternal(uri: URI) { return extHostWindow.openUri(uri, { allowTunneling: !!initData.remoteAuthority }); - } + }, + get webviewResourceRoot() { + checkProposedApiEnabled(extension); + return initData.environment.webviewResourceRoot; + }, }; if (!initData.environment.extensionTestsLocationURI) { // allow to patch env-function when running tests diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index a865a77a2038c..765a2703f7288 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -133,4 +133,8 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { driverHandle?: string; driverVerbose: boolean; webviewEndpoint?: string; + + get webviewResourceRoot(): string { + return this.webviewEndpoint ? this.webviewEndpoint + '/vscode-resource' : 'vscode-resource:'; + } } diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index 75ca5ef552aa6..f21711a4168d1 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -189,7 +189,8 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: remoteExtensionHostData.globalStorageHome, - userHome: remoteExtensionHostData.userHome + userHome: remoteExtensionHostData.userHome, + webviewResourceRoot: this._environmentService.webviewResourceRoot, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : { configuration: workspace.configuration, diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 0a153bff24454..efe66b8579cd3 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -394,7 +394,8 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: URI.file(this._environmentService.globalStorageHome), - userHome: URI.file(this._environmentService.userHome) + userHome: URI.file(this._environmentService.userHome), + webviewResourceRoot: this._environmentService.webviewResourceRoot, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { configuration: withNullAsUndefined(workspace.configuration), From 50bbabba55397c73ffd344846f5b598b0caa4287 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 07:45:22 +0200 Subject: [PATCH 067/364] web - configure menu settings --- src/vs/workbench/browser/main.contribution.ts | 53 ------------------- .../browser/workbench.contribution.ts | 30 ++++++++++- .../electron-browser/main.contribution.ts | 28 ---------- src/vs/workbench/workbench.web.main.ts | 1 - 4 files changed, 29 insertions(+), 83 deletions(-) delete mode 100644 src/vs/workbench/browser/main.contribution.ts diff --git a/src/vs/workbench/browser/main.contribution.ts b/src/vs/workbench/browser/main.contribution.ts deleted file mode 100644 index 9b19dedcf1708..0000000000000 --- a/src/vs/workbench/browser/main.contribution.ts +++ /dev/null @@ -1,53 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as nls from 'vs/nls'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; -import { isWindows, isLinux } from 'vs/base/common/platform'; - - -// Configuration -(function registerConfiguration(): void { - const registry = Registry.as(ConfigurationExtensions.Configuration); - - // Window - registry.registerConfiguration({ - 'id': 'window', - 'order': 8, - 'title': nls.localize('windowConfigurationTitle', "Window"), - 'type': 'object', - 'properties': { - 'window.menuBarVisibility': { - 'type': 'string', - 'enum': ['default', 'visible', 'toggle', 'hidden'], - 'enumDescriptions': [ - nls.localize('window.menuBarVisibility.default', "Menu is only hidden in full screen mode."), - nls.localize('window.menuBarVisibility.visible', "Menu is always visible even in full screen mode."), - nls.localize('window.menuBarVisibility.toggle', "Menu is hidden but can be displayed via Alt key."), - nls.localize('window.menuBarVisibility.hidden', "Menu is always hidden.") - ], - 'default': 'default', - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('menuBarVisibility', "Control the visibility of the menu bar. A setting of 'toggle' means that the menu bar is hidden and a single press of the Alt key will show it. By default, the menu bar will be visible, unless the window is full screen."), - 'included': isWindows || isLinux - }, - 'window.enableMenuBarMnemonics': { - 'type': 'boolean', - 'default': true, - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('enableMenuBarMnemonics', "If enabled, the main menus can be opened via Alt-key shortcuts. Disabling mnemonics allows to bind these Alt-key shortcuts to editor commands instead."), - 'included': isWindows || isLinux - }, - 'window.disableCustomMenuBarAltFocus': { - 'type': 'boolean', - 'default': false, - 'scope': ConfigurationScope.APPLICATION, - 'markdownDescription': nls.localize('disableCustomMenuBarAltFocus', "If enabled, disables the ability to focus the menu bar with the Alt-key when not set to toggle."), - 'included': isWindows || isLinux - } - } - }); -})(); \ No newline at end of file diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 07fe800bd64ef..5b46af70bad68 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -6,7 +6,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import * as nls from 'vs/nls'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; -import { isMacintosh } from 'vs/base/common/platform'; +import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform'; // Configuration (function registerConfiguration(): void { @@ -278,6 +278,34 @@ import { isMacintosh } from 'vs/base/common/platform'; 'type': 'string', 'default': isMacintosh ? '${activeEditorShort}${separator}${rootName}' : '${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}', 'markdownDescription': windowTitleDescription + }, + 'window.menuBarVisibility': { + 'type': 'string', + 'enum': ['default', 'visible', 'toggle', 'hidden'], + 'enumDescriptions': [ + nls.localize('window.menuBarVisibility.default', "Menu is only hidden in full screen mode."), + nls.localize('window.menuBarVisibility.visible', "Menu is always visible even in full screen mode."), + nls.localize('window.menuBarVisibility.toggle', "Menu is hidden but can be displayed via Alt key."), + nls.localize('window.menuBarVisibility.hidden', "Menu is always hidden.") + ], + 'default': 'default', + 'scope': ConfigurationScope.APPLICATION, + 'description': nls.localize('menuBarVisibility', "Control the visibility of the menu bar. A setting of 'toggle' means that the menu bar is hidden and a single press of the Alt key will show it. By default, the menu bar will be visible, unless the window is full screen."), + 'included': isWindows || isLinux || isWeb + }, + 'window.enableMenuBarMnemonics': { + 'type': 'boolean', + 'default': true, + 'scope': ConfigurationScope.APPLICATION, + 'description': nls.localize('enableMenuBarMnemonics', "If enabled, the main menus can be opened via Alt-key shortcuts. Disabling mnemonics allows to bind these Alt-key shortcuts to editor commands instead."), + 'included': isWindows || isLinux || isWeb + }, + 'window.disableCustomMenuBarAltFocus': { + 'type': 'boolean', + 'default': false, + 'scope': ConfigurationScope.APPLICATION, + 'markdownDescription': nls.localize('disableCustomMenuBarAltFocus', "If enabled, disables the ability to focus the menu bar with the Alt-key when not set to toggle."), + 'included': isWindows || isLinux || isWeb } } }); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 52d70f2049b14..a38fbde646df1 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -591,34 +591,6 @@ import product from 'vs/platform/product/node/product'; 'default': false, 'description': nls.localize('closeWhenEmpty', "Controls whether closing the last editor should also close the window. This setting only applies for windows that do not show folders.") }, - 'window.menuBarVisibility': { - 'type': 'string', - 'enum': ['default', 'visible', 'toggle', 'hidden'], - 'enumDescriptions': [ - nls.localize('window.menuBarVisibility.default', "Menu is only hidden in full screen mode."), - nls.localize('window.menuBarVisibility.visible', "Menu is always visible even in full screen mode."), - nls.localize('window.menuBarVisibility.toggle', "Menu is hidden but can be displayed via Alt key."), - nls.localize('window.menuBarVisibility.hidden', "Menu is always hidden.") - ], - 'default': 'default', - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('menuBarVisibility', "Control the visibility of the menu bar. A setting of 'toggle' means that the menu bar is hidden and a single press of the Alt key will show it. By default, the menu bar will be visible, unless the window is full screen."), - 'included': isWindows || isLinux - }, - 'window.enableMenuBarMnemonics': { - 'type': 'boolean', - 'default': true, - 'scope': ConfigurationScope.APPLICATION, - 'description': nls.localize('enableMenuBarMnemonics', "If enabled, the main menus can be opened via Alt-key shortcuts. Disabling mnemonics allows to bind these Alt-key shortcuts to editor commands instead."), - 'included': isWindows || isLinux - }, - 'window.disableCustomMenuBarAltFocus': { - 'type': 'boolean', - 'default': false, - 'scope': ConfigurationScope.APPLICATION, - 'markdownDescription': nls.localize('disableCustomMenuBarAltFocus', "If enabled, disables the ability to focus the menu bar with the Alt-key when not set to toggle."), - 'included': isWindows || isLinux - }, 'window.autoDetectHighContrast': { 'type': 'boolean', 'default': true, diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 562cc9ae8d283..b7c880a010588 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -9,7 +9,6 @@ import 'vs/editor/editor.all'; import 'vs/workbench/api/browser/extensionHost.contribution'; -import 'vs/workbench/browser/main.contribution'; import 'vs/workbench/browser/workbench.contribution'; import 'vs/workbench/browser/web.main'; From a9b3a096f0c91283f85c103f8a0aedf53d64b2ee Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Wed, 19 Jun 2019 07:57:08 +0200 Subject: [PATCH 068/364] Adding a11y team --- .github/commands.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/commands.yml b/.github/commands.yml index f20079caab81a..c92792325293c 100644 --- a/.github/commands.yml +++ b/.github/commands.yml @@ -105,7 +105,7 @@ { type: 'comment', name: 'a11ymas', - allowUsers: ['AccessibilityTestingTeam-TCS'], + allowUsers: ['AccessibilityTestingTeam-TCS', 'dixitsonali95', 'Mohini78', 'ChitrarupaSharma', 'mspatil110', 'umasarath52', 'v-umnaik'], action: 'updateLabels', addLabel: 'a11ymas' }, From 0a9ba2cadd47a37c57a3efb2c22c076284342dad Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 18 Jun 2019 23:38:44 -0700 Subject: [PATCH 069/364] Extract port mapping to class so it can be reused Also removes telemetry on which extensions were using localhost resources as it is no longer required --- .../contrib/webview/common/portMapping.ts | 78 ++++++++++++++++ .../electron-browser/webviewElement.ts | 90 ++----------------- 2 files changed, 87 insertions(+), 81 deletions(-) create mode 100644 src/vs/workbench/contrib/webview/common/portMapping.ts diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts new file mode 100644 index 0000000000000..877cfaed13c19 --- /dev/null +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import * as modes from 'vs/editor/common/modes'; +import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; +import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; + +export class WebviewPortMappingManager extends Disposable { + + private readonly _tunnels = new Map>(); + + constructor( + private readonly extensionLocation: URI | undefined, + private readonly mappings: () => ReadonlyArray, + private readonly tunnelService: ITunnelService + ) { + super(); + } + + public async getRedirect(url: string): Promise { + const uri = URI.parse(url); + if (uri.scheme !== 'http' && uri.scheme !== 'https') { + return undefined; + } + + const localhostMatch = /^localhost:(\d+)$/.exec(uri.authority); + if (!localhostMatch) { + return undefined; + } + + const port = +localhostMatch[1]; + for (const mapping of this.mappings()) { + if (mapping.webviewPort === port) { + if (this.extensionLocation && this.extensionLocation.scheme === REMOTE_HOST_SCHEME) { + const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); + if (tunnel) { + return url.replace( + new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), + `${uri.scheme}://localhost:${tunnel.tunnelLocalPort}/`); + } + } + + if (mapping.webviewPort !== mapping.extensionHostPort) { + return url.replace( + new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), + `${uri.scheme}://localhost:${mapping.extensionHostPort}/`); + } + } + } + + return undefined; + } + + dispose() { + super.dispose(); + + for (const tunnel of this._tunnels.values()) { + tunnel.then(tunnel => tunnel.dispose()); + } + this._tunnels.clear(); + } + + private getOrCreateTunnel(remotePort: number): Promise | undefined { + const existing = this._tunnels.get(remotePort); + if (existing) { + return existing; + } + const tunnel = this.tunnelService.openTunnel(remotePort); + if (tunnel) { + this._tunnels.set(remotePort, tunnel); + } + return tunnel; + } +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index b86e3120d0034..f0f599d10496d 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -13,19 +13,17 @@ import { endsWith } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import * as modes from 'vs/editor/common/modes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; -import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService'; +import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping'; +import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; import { Webview, WebviewContentOptions, WebviewOptions, WebviewResourceScheme } from 'vs/workbench/contrib/webview/common/webview'; import { registerFileProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols'; import { areWebviewInputOptionsEqual } from '../browser/webviewEditorService'; import { WebviewFindWidget } from '../browser/webviewFindWidget'; -import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; export interface WebviewPortMapping { readonly port: number; @@ -141,88 +139,22 @@ class WebviewProtocolProvider extends Disposable { class WebviewPortMappingProvider extends Disposable { - private readonly _tunnels = new Map>(); + private readonly _manager: WebviewPortMappingManager; constructor( session: WebviewSession, extensionLocation: URI | undefined, mappings: () => ReadonlyArray, - private readonly tunnelService: ITunnelService, - extensionId: ExtensionIdentifier | undefined, - @ITelemetryService telemetryService: ITelemetryService + tunnelService: ITunnelService, ) { super(); + this._manager = this._register(new WebviewPortMappingManager(extensionLocation, mappings, tunnelService)); - let hasLogged = false; - - session.onBeforeRequest(async (details) => { - const uri = URI.parse(details.url); - if (uri.scheme !== 'http' && uri.scheme !== 'https') { - return undefined; - } - - const localhostMatch = /^localhost:(\d+)$/.exec(uri.authority); - if (localhostMatch) { - if (!hasLogged && extensionId) { - hasLogged = true; - - /* __GDPR__ - "webview.accessLocalhost" : { - "extension" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } - */ - telemetryService.publicLog('webview.accessLocalhost', { extension: extensionId.value }); - } - - const port = +localhostMatch[1]; - for (const mapping of mappings()) { - if (mapping.webviewPort === port) { - if (extensionLocation && extensionLocation.scheme === REMOTE_HOST_SCHEME) { - const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); - if (tunnel) { - return { - redirectURL: details.url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), - `${uri.scheme}://localhost:${tunnel.tunnelLocalPort}/`) - }; - } - } - - if (mapping.webviewPort !== mapping.extensionHostPort) { - return { - redirectURL: details.url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), - `${uri.scheme}://localhost:${mapping.extensionHostPort}/`) - }; - } - } - } - } - - return undefined; + session.onBeforeRequest(async details => { + const redirect = await this._manager.getRedirect(details.url); + return redirect ? { redirectURL: redirect } : undefined; }); } - - dispose() { - super.dispose(); - - for (const tunnel of this._tunnels.values()) { - tunnel.then(tunnel => tunnel.dispose()); - } - this._tunnels.clear(); - } - - private getOrCreateTunnel(remotePort: number): Promise | undefined { - const existing = this._tunnels.get(remotePort); - if (existing) { - return existing; - } - const tunnel = this.tunnelService.openTunnel(remotePort); - if (tunnel) { - this._tunnels.set(remotePort, tunnel); - } - return tunnel; - } } class SvgBlocker extends Disposable { @@ -370,10 +302,8 @@ export class WebviewElement extends Disposable implements Webview { contentOptions: WebviewContentOptions, @IInstantiationService instantiationService: IInstantiationService, @IThemeService themeService: IThemeService, - @IEnvironmentService environmentService: IEnvironmentService, @IFileService fileService: IFileService, @ITunnelService tunnelService: ITunnelService, - @ITelemetryService telemetryService: ITelemetryService, @IConfigurationService private readonly _configurationService: IConfigurationService, ) { super(); @@ -420,8 +350,6 @@ export class WebviewElement extends Disposable implements Webview { _options.extension ? _options.extension.location : undefined, () => (this.content.options.portMappings || []), tunnelService, - _options.extension ? _options.extension.id : undefined, - telemetryService )); if (!this._options.allowSvgs) { From 29c0595809c3f1a8b1642157f5ca798287cc3fe9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Jun 2019 00:26:48 -0700 Subject: [PATCH 070/364] Add experimental port mapping support inside of iframed based webviews Hooks up a prototype of how we could support some types of port mapping inside of webviews. It uses the same service-worker based approach that we use for loading local resources inside of webviews. This does not work for loading iframes however as iframe `src` requests go to the service worker of the `src` origin (not the service worker of the parent that contains the iframe). Not sure if this can be worked around. Two alternatives if we can't: * Add api for getting the mapped port. * Dynamically rewrite the input html Both are not ideal as they may require eagerly opening tunnels (we open them lazily at the moment) --- .../contrib/webview/browser/pre/main.js | 10 +- .../webview/browser/pre/service-worker.js | 189 +++++++++++++----- .../contrib/webview/browser/webviewElement.ts | 28 ++- .../contrib/webview/common/portMapping.ts | 8 +- 4 files changed, 180 insertions(+), 55 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index d41618e61927f..5f4def45064fb 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -126,12 +126,20 @@ host.onMessage('loaded-resource', event => { registration.active.postMessage({ channel: 'loaded-resource', data: event.data.args }); }); + + host.onMessage('loaded-localhost', event => { + registration.active.postMessage({ channel: 'loaded-localhost', data: event.data.args }); + }); }); navigator.serviceWorker.addEventListener('message', event => { switch (event.data.channel) { case 'load-resource': - host.postMessage('load-resource', { path: event.data.path }); + host.postMessage('load-resource', event.data); + return; + + case 'load-localhost': + host.postMessage('load-localhost', event.data); return; } }); diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index 6c28c8ea02fae..ba8072a784d4c 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -8,25 +8,26 @@ const resourceRoot = '/vscode-resource'; /** + * @template T * @typedef {{ * resolve: () => void, - * promise: Promise - * }} ResourcePathEntry + * promise: Promise + * }} RequestStoreEntry */ /** - * Map of requested paths to responses. + * @template T */ -const resourceRequestManager = new class ResourceRequestManager { +class RequestStore { constructor() { - /** @type {Map} */ + /** @type {Map>} */ this.map = new Map(); } /** * @param {string} webviewId * @param {string} path - * @return {ResourcePathEntry | undefined} + * @return {RequestStoreEntry | undefined} */ get(webviewId, path) { return this.map.get(this._key(webviewId, path)); @@ -44,7 +45,7 @@ const resourceRequestManager = new class ResourceRequestManager { /** * @param {string} webviewId * @param {string} path - * @param {ResourcePathEntry} entry + * @param {RequestStoreEntry} entry */ set(webviewId, path, entry) { this.map.set(this._key(webviewId, path), entry); @@ -58,19 +59,34 @@ const resourceRequestManager = new class ResourceRequestManager { _key(webviewId, path) { return `${webviewId}@@@${path}`; } -}(); +} + +/** + * Map of requested paths to responses. + * + * @type {RequestStore} + */ +const resourceRequestStore = new RequestStore(); + +/** + * Map of requested paths to responses. + * + * @type {RequestStore} + */ +const localhostRequestStore = new RequestStore(); const notFoundResponse = new Response('Not Found', { status: 404, }); + self.addEventListener('message', (event) => { switch (event.data.channel) { case 'loaded-resource': { const webviewId = getWebviewIdForClient(event.source); const data = event.data.data; - const target = resourceRequestManager.get(webviewId, data.path); + const target = resourceRequestStore.get(webviewId, data.path); if (!target) { console.log('Loaded unknown resource', data.path); return; @@ -86,6 +102,20 @@ self.addEventListener('message', (event) => { } return; } + + case 'loaded-localhost': + { + const webviewId = getWebviewIdForClient(event.source); + const data = event.data.data; + const target = localhostRequestStore.get(webviewId, data.origin); + if (!target) { + console.log('Loaded unknown localhost', data.origin); + return; + } + + target.resolve(data.location); + return; + } } console.log('Unknown message'); @@ -93,48 +123,17 @@ self.addEventListener('message', (event) => { self.addEventListener('fetch', (event) => { const requestUrl = new URL(event.request.url); + console.log(requestUrl.host); - if (!requestUrl.pathname.startsWith(resourceRoot + '/')) { - return event.respondWith(fetch(event.request)); + // See if it's a resource request + if (requestUrl.origin === self.origin && requestUrl.pathname.startsWith(resourceRoot + '/')) { + return event.respondWith(processResourceRequest(event, requestUrl)); } - event.respondWith((async () => { - const client = await self.clients.get(event.clientId); - if (!client) { - console.log('Could not find inner client for request'); - return notFoundResponse.clone(); - } - - const webviewId = getWebviewIdForClient(client); - const resourcePath = requestUrl.pathname.replace(resourceRoot, ''); - - const allClients = await self.clients.matchAll({ includeUncontrolled: true }); - - // Check if we've already resolved this request - const existing = resourceRequestManager.get(webviewId, resourcePath); - if (existing) { - return existing.promise.then(r => r.clone()); - } - - // Find parent iframe - for (const client of allClients) { - const clientUrl = new URL(client.url); - if (clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId))) { - client.postMessage({ - channel: 'load-resource', - path: resourcePath - }); - - let resolve; - const promise = new Promise(r => resolve = r); - resourceRequestManager.set(webviewId, resourcePath, { resolve, promise }); - return promise.then(r => r.clone()); - } - } - - console.log('Could not find parent client for request'); - return notFoundResponse.clone(); - })()); + // See if it's a localhost request + if (requestUrl.origin !== self.origin && requestUrl.host.match(/^localhost:(\d+)$/)) { + return event.respondWith(processLocalhostRequest(event, requestUrl)); + } }); self.addEventListener('install', (event) => { @@ -145,6 +144,100 @@ self.addEventListener('activate', (event) => { event.waitUntil(self.clients.claim()); // Become available to all pages }); +async function processResourceRequest(event, requestUrl) { + const client = await self.clients.get(event.clientId); + if (!client) { + // This is expected when requesting resources on other localhost ports + // that are not spawned by vs code + console.log('Could not find inner client for request'); + return notFoundResponse.clone(); + } + + const webviewId = getWebviewIdForClient(client); + const resourcePath = requestUrl.pathname.replace(resourceRoot, ''); + + const allClients = await self.clients.matchAll({ includeUncontrolled: true }); + + // Check if we've already resolved this request + const existing = resourceRequestStore.get(webviewId, resourcePath); + if (existing) { + return existing.promise.then(r => r.clone()); + } + + // Find parent iframe + for (const client of allClients) { + const clientUrl = new URL(client.url); + if (clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId))) { + client.postMessage({ + channel: 'load-resource', + path: resourcePath + }); + + let resolve; + const promise = new Promise(r => resolve = r); + resourceRequestStore.set(webviewId, resourcePath, { resolve, promise, resolved: false }); + return promise.then(r => r.clone()); + } + } + + console.log('Could not find parent client for request'); + return notFoundResponse.clone(); +} + +/** + * @param {*} event + * @param {URL} requestUrl + */ +async function processLocalhostRequest(event, requestUrl) { + const client = await self.clients.get(event.clientId); + if (!client) { + // This is expected when requesting resources on other localhost ports + // that are not spawned by vs code + return undefined; + } + const webviewId = getWebviewIdForClient(client); + const origin = requestUrl.origin; + + const resolveRedirect = redirectOrigin => { + if (!redirectOrigin) { + return fetch(event.request); + } + const location = event.request.url.replace(new RegExp(`^${requestUrl.origin}(/|$)`), `${redirectOrigin}$1`); + return new Response(null, { + status: 302, + headers: { + Location: location + } + }); + }; + + const allClients = await self.clients.matchAll({ includeUncontrolled: true }); + + // Check if we've already resolved this request + const existing = localhostRequestStore.get(webviewId, origin); + if (existing) { + return existing.promise.then(resolveRedirect); + } + + // Find parent iframe + for (const client of allClients) { + const clientUrl = new URL(client.url); + if (clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId))) { + client.postMessage({ + channel: 'load-localhost', + origin: origin + }); + + let resolve; + const promise = new Promise(r => resolve = r); + localhostRequestStore.set(webviewId, origin, { resolve, promise }); + return promise.then(resolveRedirect); + } + } + + console.log('Could not find parent client for request'); + return notFoundResponse.clone(); +} function getWebviewIdForClient(client) { const requesterClientUrl = new URL(client.url); diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 4e2f29a199768..43bbf29ffc731 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -15,6 +15,8 @@ import { addDisposableListener, addClass } from 'vs/base/browser/dom'; import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { loadLocalResource } from 'vs/workbench/contrib/webview/common/resourceLoader'; +import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping'; +import { ITunnelService } from 'vs/platform/remote/common/tunnel'; interface WebviewContent { readonly html: string; @@ -32,11 +34,14 @@ export class IFrameWebview extends Disposable implements Webview { private readonly id: string; + private readonly _portMappingManager: WebviewPortMappingManager; + constructor( private _options: WebviewOptions, contentOptions: WebviewContentOptions, @IThemeService themeService: IThemeService, @IEnvironmentService environmentService: IEnvironmentService, + @ITunnelService tunnelService: ITunnelService, @IFileService private readonly fileService: IFileService, @IConfigurationService private readonly _configurationService: IConfigurationService, ) { @@ -45,6 +50,12 @@ export class IFrameWebview extends Disposable implements Webview { throw new Error('To use iframe based webviews, you must configure `environmentService.webviewEndpoint`'); } + this._portMappingManager = this._register(new WebviewPortMappingManager( + this._options.extension ? this._options.extension.location : undefined, + () => this.content.options.portMappings || [], + tunnelService + )); + this.content = { html: '', options: contentOptions, @@ -103,11 +114,16 @@ export class IFrameWebview extends Disposable implements Webview { case 'load-resource': { - const path = e.data.data.path; - const uri = URI.file(path); + const uri = URI.file(e.data.data.path); this.loadResource(uri); return; } + + case 'load-localhost': + { + this.localLocalhost(e.data.data.origin); + return; + } } })); @@ -305,5 +321,13 @@ export class IFrameWebview extends Disposable implements Webview { path: uri.path }); } + + private async localLocalhost(origin: string) { + const redirect = await this._portMappingManager.getRedirect(origin); + return this._send('loaded-localhost', { + origin, + location: redirect + }); + } } diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts index 877cfaed13c19..3a9b8ee056af1 100644 --- a/src/vs/workbench/contrib/webview/common/portMapping.ts +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -39,15 +39,15 @@ export class WebviewPortMappingManager extends Disposable { const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); if (tunnel) { return url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), - `${uri.scheme}://localhost:${tunnel.tunnelLocalPort}/`); + new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}(/|$)`), + `${uri.scheme}://localhost:${tunnel.tunnelLocalPort}$1`); } } if (mapping.webviewPort !== mapping.extensionHostPort) { return url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}/`), - `${uri.scheme}://localhost:${mapping.extensionHostPort}/`); + new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}(/|$)`), + `${uri.scheme}://localhost:${mapping.extensionHostPort}$1`); } } } From 01fe3fe6c1ff682e338d9abb6cc46e535e256ed3 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Jun 2019 01:09:44 -0700 Subject: [PATCH 071/364] Cleaning up service-worker impl - Reducing duplicated code - Clearer event names - Extract methods - Store data instead of requests --- .../contrib/webview/browser/pre/main.js | 24 ++- .../webview/browser/pre/service-worker.js | 140 +++++++++--------- .../contrib/webview/browser/webviewElement.ts | 6 +- 3 files changed, 83 insertions(+), 87 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 5f4def45064fb..971cbc0de23ef 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -123,24 +123,18 @@ navigator.serviceWorker.register('service-worker.js'); navigator.serviceWorker.ready.then(registration => { - host.onMessage('loaded-resource', event => { - registration.active.postMessage({ channel: 'loaded-resource', data: event.data.args }); - }); - - host.onMessage('loaded-localhost', event => { - registration.active.postMessage({ channel: 'loaded-localhost', data: event.data.args }); - }); + function forwardFromHostToWorker(channel) { + host.onMessage(channel, event => { + registration.active.postMessage({ channel: channel, data: event.data.args }); + }); + } + forwardFromHostToWorker('did-load-resource'); + forwardFromHostToWorker('did-load-localhost'); }); navigator.serviceWorker.addEventListener('message', event => { - switch (event.data.channel) { - case 'load-resource': - host.postMessage('load-resource', event.data); - return; - - case 'load-localhost': - host.postMessage('load-localhost', event.data); - return; + if (['load-resource', 'load-localhost'].includes(event.data.channel)) { + host.postMessage(event.data.channel, event.data); } }); } diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index ba8072a784d4c..d6154ba645d82 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -10,7 +10,7 @@ const resourceRoot = '/vscode-resource'; /** * @template T * @typedef {{ - * resolve: () => void, + * resolve: (x: T) => void, * promise: Promise * }} RequestStoreEntry */ @@ -36,19 +36,31 @@ class RequestStore { /** * @param {string} webviewId * @param {string} path - * @return {boolean} */ - has(webviewId, path) { - return this.map.has(this._key(webviewId, path)); + create(webviewId, path) { + const existing = this.get(webviewId, path); + if (existing) { + return existing.promise; + } + let resolve; + const promise = new Promise(r => resolve = r); + this.map.set(this._key(webviewId, path), { resolve, promise }); + return promise; } /** * @param {string} webviewId * @param {string} path - * @param {RequestStoreEntry} entry + * @param {T} result + * @return {boolean} */ - set(webviewId, path, entry) { - this.map.set(this._key(webviewId, path), entry); + resolve(webviewId, path, result) { + const entry = this.get(webviewId, path); + if (!entry) { + return false; + } + entry.resolve(result); + return true; } /** @@ -64,12 +76,12 @@ class RequestStore { /** * Map of requested paths to responses. * - * @type {RequestStore} + * @type {RequestStore<{ body: any, mime: string } | undefined>} */ const resourceRequestStore = new RequestStore(); /** - * Map of requested paths to responses. + * Map of requested localhost origins to optional redirects. * * @type {RequestStore} */ @@ -82,38 +94,27 @@ const notFoundResponse = new Response('Not Found', { self.addEventListener('message', (event) => { switch (event.data.channel) { - case 'loaded-resource': + case 'did-load-resource': { const webviewId = getWebviewIdForClient(event.source); const data = event.data.data; - const target = resourceRequestStore.get(webviewId, data.path); - if (!target) { - console.log('Loaded unknown resource', data.path); - return; - } + const response = data.status === 200 + ? { body: data.data, mime: data.mime } + : undefined; - if (data.status === 200) { - target.resolve(new Response(data.data, { - status: 200, - headers: { 'Content-Type': data.mime }, - })); - } else { - target.resolve(notFoundResponse.clone()); + if (!resourceRequestStore.resolve(webviewId, data.path, response)) { + console.log('Could not resolve unknown resource', data.path); } return; } - case 'loaded-localhost': + case 'did-load-localhost': { const webviewId = getWebviewIdForClient(event.source); const data = event.data.data; - const target = localhostRequestStore.get(webviewId, data.origin); - if (!target) { - console.log('Loaded unknown localhost', data.origin); - return; + if (!localhostRequestStore.resolve(webviewId, data.origin, data.location)) { + console.log('Could not resolve unknown localhost', data.origin); } - - target.resolve(data.location); return; } } @@ -123,7 +124,6 @@ self.addEventListener('message', (event) => { self.addEventListener('fetch', (event) => { const requestUrl = new URL(event.request.url); - console.log(requestUrl.host); // See if it's a resource request if (requestUrl.origin === self.origin && requestUrl.pathname.startsWith(resourceRoot + '/')) { @@ -147,8 +147,6 @@ self.addEventListener('activate', (event) => { async function processResourceRequest(event, requestUrl) { const client = await self.clients.get(event.clientId); if (!client) { - // This is expected when requesting resources on other localhost ports - // that are not spawned by vs code console.log('Could not find inner client for request'); return notFoundResponse.clone(); } @@ -156,32 +154,35 @@ async function processResourceRequest(event, requestUrl) { const webviewId = getWebviewIdForClient(client); const resourcePath = requestUrl.pathname.replace(resourceRoot, ''); - const allClients = await self.clients.matchAll({ includeUncontrolled: true }); + function resolveResourceEntry(entry) { + if (!entry) { + return notFoundResponse.clone(); + } + return new Response(entry.body, { + status: 200, + headers: { 'Content-Type': entry.mime } + }); + } + + const parentClient = await getOuterIframeClient(webviewId); + if (!parentClient) { + console.log('Could not find parent client for request'); + return notFoundResponse.clone(); + } // Check if we've already resolved this request const existing = resourceRequestStore.get(webviewId, resourcePath); if (existing) { - return existing.promise.then(r => r.clone()); + return existing.promise.then(resolveResourceEntry); } - // Find parent iframe - for (const client of allClients) { - const clientUrl = new URL(client.url); - if (clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId))) { - client.postMessage({ - channel: 'load-resource', - path: resourcePath - }); - - let resolve; - const promise = new Promise(r => resolve = r); - resourceRequestStore.set(webviewId, resourcePath, { resolve, promise, resolved: false }); - return promise.then(r => r.clone()); - } - } + parentClient.postMessage({ + channel: 'load-resource', + path: resourcePath + }); - console.log('Could not find parent client for request'); - return notFoundResponse.clone(); + return resourceRequestStore.create(webviewId, resourcePath) + .then(resolveResourceEntry); } /** @@ -211,7 +212,11 @@ async function processLocalhostRequest(event, requestUrl) { }); }; - const allClients = await self.clients.matchAll({ includeUncontrolled: true }); + const parentClient = await getOuterIframeClient(webviewId); + if (!parentClient) { + console.log('Could not find parent client for request'); + return notFoundResponse.clone(); + } // Check if we've already resolved this request const existing = localhostRequestStore.get(webviewId, origin); @@ -219,27 +224,24 @@ async function processLocalhostRequest(event, requestUrl) { return existing.promise.then(resolveRedirect); } - // Find parent iframe - for (const client of allClients) { - const clientUrl = new URL(client.url); - if (clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId))) { - client.postMessage({ - channel: 'load-localhost', - origin: origin - }); - - let resolve; - const promise = new Promise(r => resolve = r); - localhostRequestStore.set(webviewId, origin, { resolve, promise }); - return promise.then(resolveRedirect); - } - } + parentClient.postMessage({ + channel: 'load-localhost', + origin: origin + }); - console.log('Could not find parent client for request'); - return notFoundResponse.clone(); + return localhostRequestStore.create(webviewId, origin) + .then(resolveRedirect); } function getWebviewIdForClient(client) { const requesterClientUrl = new URL(client.url); return requesterClientUrl.search.match(/\bid=([a-z0-9-]+)/i)[1]; } + +async function getOuterIframeClient(webviewId) { + const allClients = await self.clients.matchAll({ includeUncontrolled: true }); + return allClients.find(client => { + const clientUrl = new URL(client.url); + return clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId)); + }); +} \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 43bbf29ffc731..98cfb4c089138 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -305,7 +305,7 @@ export class IFrameWebview extends Disposable implements Webview { () => (this.content.options.localResourceRoots || [])); if (result.type === 'success') { - return this._send('loaded-resource', { + return this._send('did-load-resource', { status: 200, path: uri.path, mime: result.mimeType, @@ -316,7 +316,7 @@ export class IFrameWebview extends Disposable implements Webview { // noop } - return this._send('loaded-resource', { + return this._send('did-load-resource', { status: 404, path: uri.path }); @@ -324,7 +324,7 @@ export class IFrameWebview extends Disposable implements Webview { private async localLocalhost(origin: string) { const redirect = await this._portMappingManager.getRedirect(origin); - return this._send('loaded-localhost', { + return this._send('did-load-localhost', { origin, location: redirect }); From a409cd27a50d73e21b2828eb96f0a750934a24bb Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 10:55:57 +0200 Subject: [PATCH 072/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 88789b3c9e3e4..5abd54506f5f4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "c1ec2234fb5dc62f2bf9689f41dc1cd0a507a581", + "distro": "49dcd26b8ebc282667351ed832ed309ace05c8ce", "author": { "name": "Microsoft Corporation" }, From c8843e3b0d84995a7d8493f9c932500476975c98 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 19 Jun 2019 10:58:12 +0200 Subject: [PATCH 073/364] final touch at heap service removal, #74846 --- .../workbench/api/common/extHostCommands.ts | 36 +------------------ .../workbench/api/common/extHostComments.ts | 14 ++++---- .../api/common/extHostLanguageFeatures.ts | 10 +++--- src/vs/workbench/api/common/extHostSCM.ts | 4 +-- .../workbench/api/common/extHostTreeViews.ts | 2 +- 5 files changed, 16 insertions(+), 50 deletions(-) diff --git a/src/vs/workbench/api/common/extHostCommands.ts b/src/vs/workbench/api/common/extHostCommands.ts index 5173ebb176c26..3d0840068b0bc 100644 --- a/src/vs/workbench/api/common/extHostCommands.ts +++ b/src/vs/workbench/api/common/extHostCommands.ts @@ -210,7 +210,7 @@ export class CommandsConverter { this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this); } - toInternal2(command: vscode.Command | undefined, disposables: DisposableStore): CommandDto | undefined { + toInternal(command: vscode.Command | undefined, disposables: DisposableStore): CommandDto | undefined { if (!command) { return undefined; @@ -240,40 +240,6 @@ export class CommandsConverter { return result; } - toInternal(command: vscode.Command): CommandDto; - toInternal(command: undefined): undefined; - toInternal(command: vscode.Command | undefined): CommandDto | undefined; - toInternal(command: vscode.Command | undefined): CommandDto | undefined { - - if (!command) { - return undefined; - } - - const result: CommandDto = { - $ident: undefined, - id: command.command, - title: command.title, - }; - - if (command.command && isNonEmptyArray(command.arguments)) { - // we have a contributed command with arguments. that - // means we don't want to send the arguments around - - const id = ++this._cachIdPool; - this._cache.set(id, command); - result.$ident = id; - - result.id = this._delegatingCommandId; - result.arguments = [id]; - } - - if (command.tooltip) { - result.tooltip = command.tooltip; - } - - return result; - } - fromInternal(command: modes.Command): vscode.Command | undefined { const id = ObjectIdentifier.of(command); diff --git a/src/vs/workbench/api/common/extHostComments.ts b/src/vs/workbench/api/common/extHostComments.ts index 4b76a7bece033..93b58afbd084f 100644 --- a/src/vs/workbench/api/common/extHostComments.ts +++ b/src/vs/workbench/api/common/extHostComments.ts @@ -650,9 +650,9 @@ export class ExtHostCommentThread implements vscode.CommentThread { const label = this.label; const contextValue = this.contextValue; const comments = this._comments.map(cmt => { return convertToModeComment2(this, this._commentController, cmt, this._commandsConverter, this._commentsMap, this._acceptInputDisposables.value!); }); - const acceptInputCommand = this._acceptInputCommand ? this._commandsConverter.toInternal2(this._acceptInputCommand, this._acceptInputDisposables.value) : undefined; - const additionalCommands = (this._additionalCommands ? this._additionalCommands.map(x => this._commandsConverter.toInternal2(x, this._acceptInputDisposables.value!)) : []) as CommandDto[]; - const deleteCommand = this._deleteCommand ? this._commandsConverter.toInternal2(this._deleteCommand, this._acceptInputDisposables.value) : undefined; + const acceptInputCommand = this._acceptInputCommand ? this._commandsConverter.toInternal(this._acceptInputCommand, this._acceptInputDisposables.value) : undefined; + const additionalCommands = (this._additionalCommands ? this._additionalCommands.map(x => this._commandsConverter.toInternal(x, this._acceptInputDisposables.value!)) : []) as CommandDto[]; + const deleteCommand = this._deleteCommand ? this._commandsConverter.toInternal(this._deleteCommand, this._acceptInputDisposables.value) : undefined; const collapsibleState = convertToCollapsibleState(this._collapseState); this._proxy.$updateCommentThread( @@ -951,9 +951,9 @@ function convertToModeComment2(thread: ExtHostCommentThread, commentController: userName: vscodeComment.author ? vscodeComment.author.name : vscodeComment.userName, userIconPath: iconPath, isDraft: vscodeComment.isDraft, - selectCommand: vscodeComment.selectCommand ? commandsConverter.toInternal2(vscodeComment.selectCommand, disposables) : undefined, - editCommand: vscodeComment.editCommand ? commandsConverter.toInternal2(vscodeComment.editCommand, disposables) : undefined, - deleteCommand: vscodeComment.deleteCommand ? commandsConverter.toInternal2(vscodeComment.deleteCommand, disposables) : undefined, + selectCommand: vscodeComment.selectCommand ? commandsConverter.toInternal(vscodeComment.selectCommand, disposables) : undefined, + editCommand: vscodeComment.editCommand ? commandsConverter.toInternal(vscodeComment.editCommand, disposables) : undefined, + deleteCommand: vscodeComment.deleteCommand ? commandsConverter.toInternal(vscodeComment.deleteCommand, disposables) : undefined, label: vscodeComment.label, commentReactions: reactions ? reactions.map(reaction => convertToReaction2(commentController.reactionProvider, reaction)) : undefined }; @@ -971,7 +971,7 @@ function convertToComment(provider: vscode.DocumentCommentProvider | vscode.Work userIconPath: iconPath, canEdit: canEdit, canDelete: canDelete, - selectCommand: vscodeComment.command ? commandsConverter.toInternal2(vscodeComment.command, disposables) : undefined, + selectCommand: vscodeComment.command ? commandsConverter.toInternal(vscodeComment.command, disposables) : undefined, isDraft: vscodeComment.isDraft, commentReactions: vscodeComment.commentReactions ? vscodeComment.commentReactions.map(reaction => convertToReaction(provider, reaction)) : undefined }; diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index 661e98948c922..4aefb1cc5d6f1 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -133,7 +133,7 @@ class CodeLensAdapter { result.lenses.push({ cacheId: [cacheId, i], range: typeConvert.Range.from(lenses[i].range), - command: this._commands.toInternal2(lenses[i].command, disposables) + command: this._commands.toInternal(lenses[i].command, disposables) }); } @@ -167,7 +167,7 @@ class CodeLensAdapter { } newLens = newLens || lens; - symbol.command = this._commands.toInternal2(newLens.command || CodeLensAdapter._badCmd, disposables); + symbol.command = this._commands.toInternal(newLens.command || CodeLensAdapter._badCmd, disposables); return symbol; }); } @@ -368,7 +368,7 @@ class CodeActionAdapter { actions.push({ _isSynthetic: true, title: candidate.title, - command: this._commands.toInternal2(candidate, disposables), + command: this._commands.toInternal(candidate, disposables), }); } else { if (codeActionContext.only) { @@ -382,7 +382,7 @@ class CodeActionAdapter { // new school: convert code action actions.push({ title: candidate.title, - command: candidate.command && this._commands.toInternal2(candidate.command, disposables), + command: candidate.command && this._commands.toInternal(candidate.command, disposables), diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from), edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit), kind: candidate.kind && candidate.kind.value, @@ -735,7 +735,7 @@ class SuggestAdapter { i: item.keepWhitespace ? modes.CompletionItemInsertTextRule.KeepWhitespace : 0, k: item.commitCharacters, l: item.additionalTextEdits && item.additionalTextEdits.map(typeConvert.TextEdit.from), - m: this._commands.toInternal2(item.command, disposables), + m: this._commands.toInternal(item.command, disposables), }; // 'insertText'-logic diff --git a/src/vs/workbench/api/common/extHostSCM.ts b/src/vs/workbench/api/common/extHostSCM.ts index 5ae57de0204d5..675201e622fa5 100644 --- a/src/vs/workbench/api/common/extHostSCM.ts +++ b/src/vs/workbench/api/common/extHostSCM.ts @@ -427,7 +427,7 @@ class ExtHostSourceControl implements vscode.SourceControl { this._acceptInputCommand = acceptInputCommand; - const internal = this._commands.converter.toInternal2(acceptInputCommand, this._acceptInputDisposables.value); + const internal = this._commands.converter.toInternal(acceptInputCommand, this._acceptInputDisposables.value); this._proxy.$updateSourceControl(this.handle, { acceptInputCommand: internal }); } @@ -447,7 +447,7 @@ class ExtHostSourceControl implements vscode.SourceControl { this._statusBarCommands = statusBarCommands; - const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal2(c, this._statusBarDisposables.value!)) as CommandDto[]; + const internal = (statusBarCommands || []).map(c => this._commands.converter.toInternal(c, this._statusBarDisposables.value!)) as CommandDto[]; this._proxy.$updateSourceControl(this.handle, { statusBarCommands: internal }); } diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index ac0c9878b0e87..0524871953aa5 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -452,7 +452,7 @@ class ExtHostTreeView extends Disposable { description: extensionTreeItem.description, resourceUri: extensionTreeItem.resourceUri, tooltip: typeof extensionTreeItem.tooltip === 'string' ? extensionTreeItem.tooltip : undefined, - command: extensionTreeItem.command ? this.commands.toInternal2(extensionTreeItem.command, disposable) : undefined, + command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command, disposable) : undefined, contextValue: extensionTreeItem.contextValue, icon, iconDark: this.getDarkIconPath(extensionTreeItem) || icon, From 300e4bdf2ad42c4b54643dc668d2fac9c7c6cc47 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 19 Jun 2019 11:18:32 +0200 Subject: [PATCH 074/364] fix #75746 --- src/vs/workbench/api/common/extHostApiCommands.ts | 13 ++++++++++--- .../electron-browser/api/extHostApiCommands.test.ts | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/common/extHostApiCommands.ts b/src/vs/workbench/api/common/extHostApiCommands.ts index 2da50e9c3f40f..4d78f9c67f3b5 100644 --- a/src/vs/workbench/api/common/extHostApiCommands.ts +++ b/src/vs/workbench/api/common/extHostApiCommands.ts @@ -18,6 +18,7 @@ import { CustomCodeAction } from 'vs/workbench/api/common/extHostLanguageFeature import { ICommandsExecutor, OpenFolderAPICommand, DiffAPICommand, OpenAPICommand, RemoveFromRecentlyOpenedAPICommand, SetEditorLayoutAPICommand, OpenIssueReporter } from './apiCommands'; import { EditorGroupLayout } from 'vs/workbench/services/editor/common/editorGroupsService'; import { isFalsyOrEmpty } from 'vs/base/common/arrays'; +import { IRange } from 'vs/editor/common/core/range'; export class ExtHostApiCommands { @@ -414,15 +415,21 @@ export class ExtHostApiCommands { }); } - private _executeSelectionRangeProvider(resource: URI, positions: types.Position[]): Promise { + private _executeSelectionRangeProvider(resource: URI, positions: types.Position[]): Promise { const pos = positions.map(typeConverters.Position.from); const args = { resource, position: pos[0], positions: pos }; - return this._commands.executeCommand('_executeSelectionRangeProvider', args).then(result => { - return result.map(oneResult => oneResult.map(typeConverters.SelectionRange.to)); + return this._commands.executeCommand('_executeSelectionRangeProvider', args).then(result => { + return result.map(ranges => { + let node: types.SelectionRange | undefined; + for (const range of ranges.reverse()) { + node = new types.SelectionRange(typeConverters.Range.to(range), node); + } + return node!; + }); }); } diff --git a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts index 047d78070f36f..8eb327c11c7aa 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostApiCommands.test.ts @@ -796,9 +796,9 @@ suite('ExtHostLanguageFeatureCommands', function () { })); await rpcProtocol.sync(); - let value = await commands.executeCommand('vscode.executeSelectionRangeProvider', model.uri, [new types.Position(0, 10)]); + let value = await commands.executeCommand('vscode.executeSelectionRangeProvider', model.uri, [new types.Position(0, 10)]); assert.equal(value.length, 1); - assert.ok(value[0].length >= 2); + assert.ok(value[0].parent); }); }); From 613447d6b3f458ef7fee227e3876303bf5184580 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 11:26:22 +0200 Subject: [PATCH 075/364] start to comment out tests (for #74898) --- scripts/test-integration.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 3d397ed204ee7..a9058442dce28 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -21,9 +21,9 @@ cd $ROOT ./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started ./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -mkdir -p $ROOT/extensions/emmet/test-fixtures -./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -rm -rf $ROOT/extensions/emmet/test-fixtures +# mkdir -p $ROOT/extensions/emmet/test-fixtures +# ./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +# rm -rf $ROOT/extensions/emmet/test-fixtures if [ -f ./resources/server/test/test-remote-integration.sh ]; then ./resources/server/test/test-remote-integration.sh From 659c8c00c83d5823969501b1af325836c59ed22f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 11:41:52 +0200 Subject: [PATCH 076/364] fixing the workbench html adopting to server --- src/vs/code/browser/workbench/workbench.html | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 679b872a315c9..581fe5c2667c6 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -6,6 +6,7 @@ + @@ -15,14 +16,7 @@ From 3bffb1561c7021c3abadd14273814ee5f37ba072 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 19 Jun 2019 11:43:56 +0200 Subject: [PATCH 077/364] code doesn't open in remote-wsl under WSL2. For microsoft/vscode-remote-release#714 --- resources/win32/bin/code.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/resources/win32/bin/code.sh b/resources/win32/bin/code.sh index b1a0f7e4f3e66..606fb108fe5b0 100644 --- a/resources/win32/bin/code.sh +++ b/resources/win32/bin/code.sh @@ -11,8 +11,18 @@ VSCODE_PATH="$(dirname "$(dirname "$(realpath "$0")")")" ELECTRON="$VSCODE_PATH/$NAME.exe" if grep -qi Microsoft /proc/version; then # in a wsl shell - WSL_BUILD=$(uname -r | sed -E 's/^.+-([0-9]+)-[Mm]icrosoft/\1/') - if [ $WSL_BUILD -ge 17063 ] 2> /dev/null; then + if ! [ -z "$WSL_DISTRO_NAME"]; then + # $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2 + WSL_BUILD=18362 + else + WSL_BUILD=$(uname -r | sed -E 's/^.+-([0-9]+)-Microsoft/\1/') + if ! [ -z "$WSL_BUILD" ]; then + WSL_BUILD=0 + fi + fi + + if [ $WSL_BUILD -ge 17063 ]; then + # $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2 # WSLPATH is available since WSL build 17046 # WSLENV is available since WSL build 17063 export WSLENV=ELECTRON_RUN_AS_NODE/w:$WSLENV From 4a7e7b5cefa231ef27e1db1698859b1d6aa734d2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 11:48:42 +0200 Subject: [PATCH 078/364] comment out more tests (#74898) --- .../src/singlefolder-tests/workspace.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index dc700abdf1b89..67059e58c5069 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -513,28 +513,28 @@ suite('workspace-namespace', () => { }); }); - test('findFiles', () => { + (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles', () => { return vscode.workspace.findFiles('**/*.png').then((res) => { assert.equal(res.length, 2); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); }); - test('findFiles - exclude', () => { + (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles - exclude', () => { return vscode.workspace.findFiles('**/*.png').then((res) => { assert.equal(res.length, 2); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); }); - test('findFiles, exclude', () => { + (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles, exclude', () => { return vscode.workspace.findFiles('**/*.png', '**/sub/**').then((res) => { assert.equal(res.length, 1); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); }); - test('findFiles, cancellation', () => { + (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles, cancellation', () => { const source = new vscode.CancellationTokenSource(); const token = source.token; // just to get an instance first @@ -545,7 +545,7 @@ suite('workspace-namespace', () => { }); }); - test('findTextInFiles', async () => { + (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findTextInFiles', async () => { const options: vscode.FindTextInFilesOptions = { include: '*.ts', previewOptions: { @@ -565,7 +565,7 @@ suite('workspace-namespace', () => { assert.equal(vscode.workspace.asRelativePath(match.uri), '10linefile.ts'); }); - test('findTextInFiles, cancellation', async () => { + (process.platform === 'win32' ? suite.skip /* https://github.com/microsoft/vscode/issues/74898 */ : suite)('findTextInFiles, cancellation', async () => { const results: vscode.TextSearchResult[] = []; const cancellation = new vscode.CancellationTokenSource(); cancellation.cancel(); From 781e61bf568a5e99756597c21ae2e3d3d293b1a0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 19 Jun 2019 11:52:35 +0200 Subject: [PATCH 079/364] fix double encoding issue, https://github.com/microsoft/vscode-azure-account/issues/142 --- src/vs/editor/browser/services/openerService.ts | 2 +- src/vs/workbench/api/browser/mainThreadWindow.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index c175034f9699f..9cfeed27dd059 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -55,7 +55,7 @@ export class OpenerService implements IOpenerService { if (equalsIgnoreCase(scheme, Schemas.http) || equalsIgnoreCase(scheme, Schemas.https) || equalsIgnoreCase(scheme, Schemas.mailto)) { // open http or default mail application - dom.windowOpenNoOpener(encodeURI(resource.toString(true))); + dom.windowOpenNoOpener(resource.toString()); return Promise.resolve(true); } else if (equalsIgnoreCase(scheme, Schemas.command)) { diff --git a/src/vs/workbench/api/browser/mainThreadWindow.ts b/src/vs/workbench/api/browser/mainThreadWindow.ts index 4c5b038c2313e..c9a212e48632f 100644 --- a/src/vs/workbench/api/browser/mainThreadWindow.ts +++ b/src/vs/workbench/api/browser/mainThreadWindow.ts @@ -59,7 +59,7 @@ export class MainThreadWindow implements MainThreadWindowShape { } } - return this.windowsService.openExternal(encodeURI(uri.toString(true))); + return this.windowsService.openExternal(uri.toString()); } private getLocalhostPort(uri: URI): number | undefined { From 021839444b8266714e232206348625e9884d1b7e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 11:54:27 +0200 Subject: [PATCH 080/364] take web related changes --- build/lib/standalone.ts | 1 + src/vs/code/browser/workbench/workbench.html | 45 +++++++++++--------- src/vs/web-configuration-init.js.js | 8 ++++ 3 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 src/vs/web-configuration-init.js.js diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 79cdeeb455c2b..44d89d22e5a04 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -108,6 +108,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str 'vs/css.d.ts', 'vs/css.js', 'vs/loader.js', + 'vs/web-configuration-init.js', 'vs/nls.build.js', 'vs/nls.d.ts', 'vs/nls.js', diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 581fe5c2667c6..e0a187ab40104 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -1,24 +1,29 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/vs/web-configuration-init.js.js b/src/vs/web-configuration-init.js.js new file mode 100644 index 0000000000000..6227c2ca9220a --- /dev/null +++ b/src/vs/web-configuration-init.js.js @@ -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. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +self.WORKBENCH_WEB_CONFIGURATION = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings')); From e3516139a5cd5142f0be228128d1c6f93d32b402 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:00:47 +0200 Subject: [PATCH 081/364] fix file name --- .../{web-configuration-init.js.js => web-configuration-init.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/vs/{web-configuration-init.js.js => web-configuration-init.js} (100%) diff --git a/src/vs/web-configuration-init.js.js b/src/vs/web-configuration-init.js similarity index 100% rename from src/vs/web-configuration-init.js.js rename to src/vs/web-configuration-init.js From 70115766a64b236d0cb796badd06fd0535203f93 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:03:28 +0200 Subject: [PATCH 082/364] update environment changes --- src/vs/platform/environment/common/environment.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index b2d41431207f8..30a8d1fd589df 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -69,6 +69,7 @@ export interface ParsedArgs { 'driver-verbose'?: boolean; remote?: string; 'disable-user-env-probe'?: boolean; + 'enable-remote-auto-shutdown'?: boolean; } export const IEnvironmentService = createDecorator('environmentService'); From 4ac1c6fa7a5f21cfe60d6eeb06839c360572b187 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:04:19 +0200 Subject: [PATCH 083/364] rename docker extension --- src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index 57ec2510560ec..071c367c648f6 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -151,7 +151,7 @@ const extensionPacks: ExtensionSuggestion[] = [ // { name: localize('welcomePage.go', "Go"), id: 'lukehoban.go' }, { name: localize('welcomePage.php', "PHP"), id: 'felixfbecker.php-pack' }, { name: localize('welcomePage.azure', "Azure"), title: localize('welcomePage.showAzureExtensions', "Show Azure extensions"), id: 'workbench.extensions.action.showAzureExtensions', isCommand: true }, - { name: localize('welcomePage.docker', "Docker"), id: 'peterjausovec.vscode-docker' }, + { name: localize('welcomePage.docker', "Docker"), id: 'ms-azuretools.vscode-docker' }, ]; const keymapExtensions: ExtensionSuggestion[] = [ From 1db16ff18b63bf781a3c4df17895d6b443f7f522 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 19 Jun 2019 12:06:37 +0200 Subject: [PATCH 084/364] fix #75263 --- .../parts/editor/breadcrumbsControl.ts | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 21cae306f4e9f..6590a90c12c94 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -327,6 +327,7 @@ export class BreadcrumbsControl { // show picker let picker: BreadcrumbsPicker; + let pickerAnchor: { x: number; y: number }; let editor = this._getActiveCodeEditor(); let editorDecorations: string[] = []; let editorViewState: ICodeEditorViewState | undefined; @@ -393,34 +394,37 @@ export class BreadcrumbsControl { ); }, getAnchor: () => { - let maxInnerWidth = window.innerWidth - 8 /*a little less the full widget*/; - let maxHeight = Math.min(window.innerHeight * 0.7, 300); - - let pickerWidth = Math.min(maxInnerWidth, Math.max(240, maxInnerWidth / 4.17)); - let pickerArrowSize = 8; - let pickerArrowOffset: number; - - let data = dom.getDomNodePagePosition(event.node.firstChild as HTMLElement); - let y = data.top + data.height + pickerArrowSize; - if (y + maxHeight >= window.innerHeight) { - maxHeight = window.innerHeight - y - 30 /* room for shadow and status bar*/; - } - let x = data.left; - if (x + pickerWidth >= maxInnerWidth) { - x = maxInnerWidth - pickerWidth; - } - if (event.payload instanceof StandardMouseEvent) { - let maxPickerArrowOffset = pickerWidth - 2 * pickerArrowSize; - pickerArrowOffset = event.payload.posx - x; - if (pickerArrowOffset > maxPickerArrowOffset) { - x = Math.min(maxInnerWidth - pickerWidth, x + pickerArrowOffset - maxPickerArrowOffset); - pickerArrowOffset = maxPickerArrowOffset; + if (!pickerAnchor) { + let maxInnerWidth = window.innerWidth - 8 /*a little less the full widget*/; + let maxHeight = Math.min(window.innerHeight * 0.7, 300); + + let pickerWidth = Math.min(maxInnerWidth, Math.max(240, maxInnerWidth / 4.17)); + let pickerArrowSize = 8; + let pickerArrowOffset: number; + + let data = dom.getDomNodePagePosition(event.node.firstChild as HTMLElement); + let y = data.top + data.height + pickerArrowSize; + if (y + maxHeight >= window.innerHeight) { + maxHeight = window.innerHeight - y - 30 /* room for shadow and status bar*/; + } + let x = data.left; + if (x + pickerWidth >= maxInnerWidth) { + x = maxInnerWidth - pickerWidth; + } + if (event.payload instanceof StandardMouseEvent) { + let maxPickerArrowOffset = pickerWidth - 2 * pickerArrowSize; + pickerArrowOffset = event.payload.posx - x; + if (pickerArrowOffset > maxPickerArrowOffset) { + x = Math.min(maxInnerWidth - pickerWidth, x + pickerArrowOffset - maxPickerArrowOffset); + pickerArrowOffset = maxPickerArrowOffset; + } + } else { + pickerArrowOffset = (data.left + (data.width * 0.3)) - x; } - } else { - pickerArrowOffset = (data.left + (data.width * 0.3)) - x; + picker.show(element, maxHeight, pickerWidth, pickerArrowSize, Math.max(0, pickerArrowOffset)); + pickerAnchor = { x, y }; } - picker.show(element, maxHeight, pickerWidth, pickerArrowSize, Math.max(0, pickerArrowOffset)); - return { x, y }; + return pickerAnchor; }, onHide: (data) => { if (editor) { From 3f317783b63a56e1c17ca939cd6a54590252b199 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:18:00 +0200 Subject: [PATCH 085/364] Move remote user data from web configuration --- src/vs/code/browser/workbench/workbench.html | 2 ++ src/vs/web-configuration-init.js | 1 + .../services/environment/browser/environmentService.ts | 2 +- src/vs/workbench/workbench.web.api.ts | 9 +++++++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index e0a187ab40104..17cef3a4f014b 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -12,6 +12,8 @@ content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote:; media-src 'none'; child-src 'self' {{WEBVIEW_ENDPOINT}}; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' blob: vscode-remote:;"> + + diff --git a/src/vs/web-configuration-init.js b/src/vs/web-configuration-init.js index 6227c2ca9220a..3a51acbee18aa 100644 --- a/src/vs/web-configuration-init.js +++ b/src/vs/web-configuration-init.js @@ -6,3 +6,4 @@ 'use strict'; self.WORKBENCH_WEB_CONFIGURATION = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings')); +self.REMOTE_USER_DATA_URI = JSON.parse(document.getElementById('vscode-remote-user-data-uri').getAttribute('data-settings')); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index a865a77a2038c..c975c0e2a0853 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -70,7 +70,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { this.configuration.remoteAuthority = configuration.remoteAuthority; - this.appSettingsHome = joinPath(URI.revive(configuration.userDataUri), 'User'); + this.appSettingsHome = joinPath(URI.revive((self).REMOTE_USER_DATA_URI), 'User'); this.settingsResource = joinPath(this.appSettingsHome, 'settings.json'); this.keybindingsResource = joinPath(this.appSettingsHome, 'keybindings.json'); diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 326b1f485c351..d8070d0ce4c01 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -6,16 +6,21 @@ import 'vs/workbench/workbench.web.main'; import { main } from 'vs/workbench/browser/web.main'; import { UriComponents } from 'vs/base/common/uri'; +import { Event } from 'vs/base/common/event'; export interface IWorkbenchConstructionOptions { remoteAuthority: string; - userDataUri: UriComponents; - webviewEndpoint?: string; folderUri?: UriComponents; workspaceUri?: UriComponents; + + userData?: { + read(key: string): Promise; + write(key: string, value: string): Promise; + onDidChange: Event; + }; } function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise { From 25405607d9129c8be97d52e9a0673094b2785f37 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:19:36 +0200 Subject: [PATCH 086/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5abd54506f5f4..e26fd27ed2498 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "49dcd26b8ebc282667351ed832ed309ace05c8ce", + "distro": "553b1cdbb30d86c59f5f7314acdc3508908cedac", "author": { "name": "Microsoft Corporation" }, From 664dacc8b2c0e52a62fc6244ab4c0e38382dc45e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:30:16 +0200 Subject: [PATCH 087/364] move connection auth token out of web configuration --- build/lib/standalone.ts | 1 - src/vs/code/browser/workbench/workbench.html | 5 ++--- src/vs/code/browser/workbench/workbench.js | 6 +----- src/vs/platform/sign/browser/signService.ts | 2 +- src/vs/web-configuration-init.js | 9 --------- .../services/environment/browser/environmentService.ts | 2 +- 6 files changed, 5 insertions(+), 20 deletions(-) delete mode 100644 src/vs/web-configuration-init.js diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 44d89d22e5a04..79cdeeb455c2b 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -108,7 +108,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str 'vs/css.d.ts', 'vs/css.js', 'vs/loader.js', - 'vs/web-configuration-init.js', 'vs/nls.build.js', 'vs/nls.d.ts', 'vs/nls.js', diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 17cef3a4f014b..dc3e933ec7487 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -14,6 +14,8 @@ + + @@ -22,9 +24,6 @@ - - - diff --git a/src/vs/code/browser/workbench/workbench.js b/src/vs/code/browser/workbench/workbench.js index 3dfc2e31515e3..5915d0531cf8b 100644 --- a/src/vs/code/browser/workbench/workbench.js +++ b/src/vs/code/browser/workbench/workbench.js @@ -3,12 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -//@ts-check 'use strict'; (function () { - // @ts-ignore require.config({ baseUrl: `${window.location.origin}/out`, paths: { @@ -20,9 +18,7 @@ } }); - // @ts-ignore require(['vs/workbench/workbench.web.api'], function (api) { - // @ts-ignore - api.create(document.body, self.WORKBENCH_WEB_CONFIGURATION); + api.create(document.body, JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings'))); }); })(); \ No newline at end of file diff --git a/src/vs/platform/sign/browser/signService.ts b/src/vs/platform/sign/browser/signService.ts index 5c1919ba88fb3..501ab8939d4ce 100644 --- a/src/vs/platform/sign/browser/signService.ts +++ b/src/vs/platform/sign/browser/signService.ts @@ -11,6 +11,6 @@ export class SignService implements ISignService { _serviceBrand: ServiceIdentifier; async sign(value: string): Promise { - return Promise.resolve((self).WORKBENCH_WEB_CONFIGURATION.connectionAuthToken); + return Promise.resolve(document.getElementById('vscode-remote-connection-token')!.getAttribute('data-settings')!); } } \ No newline at end of file diff --git a/src/vs/web-configuration-init.js b/src/vs/web-configuration-init.js deleted file mode 100644 index 3a51acbee18aa..0000000000000 --- a/src/vs/web-configuration-init.js +++ /dev/null @@ -1,9 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -self.WORKBENCH_WEB_CONFIGURATION = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings')); -self.REMOTE_USER_DATA_URI = JSON.parse(document.getElementById('vscode-remote-user-data-uri').getAttribute('data-settings')); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index c975c0e2a0853..8ef1e38761c04 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -70,7 +70,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { this.configuration.remoteAuthority = configuration.remoteAuthority; - this.appSettingsHome = joinPath(URI.revive((self).REMOTE_USER_DATA_URI), 'User'); + this.appSettingsHome = joinPath(URI.revive(JSON.parse(document.getElementById('vscode-remote-user-data-uri')!.getAttribute('data-settings')!)), 'User'); this.settingsResource = joinPath(this.appSettingsHome, 'settings.json'); this.keybindingsResource = joinPath(this.appSettingsHome, 'keybindings.json'); From a012a5929ea544c8625d36e050b25254a202be07 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:30:52 +0200 Subject: [PATCH 088/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e26fd27ed2498..59ec4eafc4f6b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "553b1cdbb30d86c59f5f7314acdc3508908cedac", + "distro": "42a63f3c8b7d02f13b3af1f2666b293af0951c9a", "author": { "name": "Microsoft Corporation" }, From 8a34940782c1afe00a8709b39647dffbd74ecbe2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 12:43:18 +0200 Subject: [PATCH 089/364] revert fix #75354 --- src/vs/workbench/contrib/scm/browser/scmActivity.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmActivity.ts b/src/vs/workbench/contrib/scm/browser/scmActivity.ts index 2bcd79a66f87d..de8d68429cfca 100644 --- a/src/vs/workbench/contrib/scm/browser/scmActivity.ts +++ b/src/vs/workbench/contrib/scm/browser/scmActivity.ts @@ -189,20 +189,12 @@ export class StatusBarController implements IWorkbenchContribution { const disposables = new DisposableStore(); for (const c of commands) { - const statusId = `status.scm.${repository.provider.id}.${c.tooltip}`; // needs to be unique, but c.id is too random - let statusLabel: string; - if (c.tooltip) { - statusLabel = localize('status.scm', "Source Control ({0}): {1}", repository.provider.label, c.tooltip.replace('...', '')); - } else { - statusLabel = localize('status.scm.short', "Source Control ({0})", repository.provider.label); - } - disposables.add(this.statusbarService.addEntry({ text: c.title, tooltip: `${label} - ${c.tooltip}`, command: c.id, arguments: c.arguments - }, statusId, statusLabel, MainThreadStatusBarAlignment.LEFT, 10000)); + }, 'status.scm', localize('status.scm', "Source Control"), MainThreadStatusBarAlignment.LEFT, 10000)); } this.statusBarDisposable = disposables; From db21a9a803ee9e45ea0ee0c2e22440c17d86c18f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 12:50:31 +0200 Subject: [PATCH 090/364] separte log contributions for web --- .../contrib/logs/common/logs.contribution.ts | 71 ++----------------- .../electron-browser/logs.contribution.ts | 68 ++++++++++++++++++ .../remote/common/remote.contribution.ts | 20 +++++- src/vs/workbench/workbench.main.ts | 1 + 4 files changed, 92 insertions(+), 68 deletions(-) create mode 100644 src/vs/workbench/contrib/logs/electron-browser/logs.contribution.ts diff --git a/src/vs/workbench/contrib/logs/common/logs.contribution.ts b/src/vs/workbench/contrib/logs/common/logs.contribution.ts index 12347d6ea7e0c..fa261bc537bd6 100644 --- a/src/vs/workbench/contrib/logs/common/logs.contribution.ts +++ b/src/vs/workbench/contrib/logs/common/logs.contribution.ts @@ -4,74 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { join } from 'vs/base/common/path'; import { Registry } from 'vs/platform/registry/common/platform'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { IOutputChannelRegistry, Extensions as OutputExt, } from 'vs/workbench/contrib/output/common/output'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import * as Constants from 'vs/workbench/contrib/logs/common/logConstants'; import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { OpenLogsFolderAction, SetLogLevelAction } from 'vs/workbench/contrib/logs/common/logsActions'; -import { ILogService, LogLevel } from 'vs/platform/log/common/log'; -import { IFileService, FileChangeType } from 'vs/platform/files/common/files'; -import { dirname, joinPath } from 'vs/base/common/resources'; -import { IRemoteAgentService, RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { SetLogLevelAction } from 'vs/workbench/contrib/logs/common/logsActions'; -class LogOutputChannels extends Disposable implements IWorkbenchContribution { - - constructor( - @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, - @ILogService logService: ILogService, - @IFileService private readonly fileService: IFileService, - @IRemoteAgentService remoteAgentService: IRemoteAgentService - ) { - super(); - this.registerLogChannel(Constants.mainLogChannelId, nls.localize('mainLog', "Main"), URI.file(join(environmentService.logsPath, `main.log`))); - this.registerLogChannel(Constants.sharedLogChannelId, nls.localize('sharedLog', "Shared"), URI.file(join(environmentService.logsPath, `sharedprocess.log`))); - this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), URI.file(join(environmentService.logsPath, `renderer${environmentService.configuration.windowId}.log`))); - remoteAgentService.getEnvironment().then(remoteEnv => { - if (remoteEnv) { - const outputChannelRegistry = Registry.as(OutputExt.OutputChannels); - outputChannelRegistry.registerChannel({ id: 'remoteExtensionLog', label: nls.localize('remoteExtensionLog', "Remote Server"), file: joinPath(remoteEnv.logsPath, `${RemoteExtensionLogFileName}.log`), log: true }); - } - }); - - const registerTelemetryChannel = (level: LogLevel) => { - if (level === LogLevel.Trace && !Registry.as(OutputExt.OutputChannels).getChannel(Constants.telemetryLogChannelId)) { - this.registerLogChannel(Constants.telemetryLogChannelId, nls.localize('telemetryLog', "Telemetry"), URI.file(join(environmentService.logsPath, `telemetry.log`))); - } - }; - registerTelemetryChannel(logService.getLevel()); - logService.onDidChangeLogLevel(registerTelemetryChannel); - - const workbenchActionsRegistry = Registry.as(WorkbenchActionExtensions.WorkbenchActions); - const devCategory = nls.localize('developer', "Developer"); - workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenLogsFolderAction, OpenLogsFolderAction.ID, OpenLogsFolderAction.LABEL), 'Developer: Open Logs Folder', devCategory); - workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(SetLogLevelAction, SetLogLevelAction.ID, SetLogLevelAction.LABEL), 'Developer: Set Log Level...', devCategory); - } - - private async registerLogChannel(id: string, label: string, file: URI): Promise { - const outputChannelRegistry = Registry.as(OutputExt.OutputChannels); - const exists = await this.fileService.exists(file); - if (exists) { - outputChannelRegistry.registerChannel({ id, label, file, log: true }); - return; - } - - const watcher = this.fileService.watch(dirname(file)); - const disposable = this.fileService.onFileChanges(e => { - if (e.contains(file, FileChangeType.ADDED)) { - watcher.dispose(); - disposable.dispose(); - outputChannelRegistry.registerChannel({ id, label, file, log: true }); - } - }); - } - -} - -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LogOutputChannels, LifecyclePhase.Restored); \ No newline at end of file +const workbenchActionsRegistry = Registry.as(WorkbenchActionExtensions.WorkbenchActions); +const devCategory = nls.localize('developer', "Developer"); +workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(SetLogLevelAction, SetLogLevelAction.ID, SetLogLevelAction.LABEL), 'Developer: Set Log Level...', devCategory); \ No newline at end of file diff --git a/src/vs/workbench/contrib/logs/electron-browser/logs.contribution.ts b/src/vs/workbench/contrib/logs/electron-browser/logs.contribution.ts new file mode 100644 index 0000000000000..d8d381fa5252b --- /dev/null +++ b/src/vs/workbench/contrib/logs/electron-browser/logs.contribution.ts @@ -0,0 +1,68 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { join } from 'vs/base/common/path'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { IOutputChannelRegistry, Extensions as OutputExt, } from 'vs/workbench/contrib/output/common/output'; +import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { URI } from 'vs/base/common/uri'; +import * as Constants from 'vs/workbench/contrib/logs/common/logConstants'; +import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { OpenLogsFolderAction } from 'vs/workbench/contrib/logs/common/logsActions'; +import { ILogService, LogLevel } from 'vs/platform/log/common/log'; +import { IFileService, FileChangeType } from 'vs/platform/files/common/files'; +import { dirname } from 'vs/base/common/resources'; + +class LogOutputChannels extends Disposable implements IWorkbenchContribution { + + constructor( + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @ILogService logService: ILogService, + @IFileService private readonly fileService: IFileService + ) { + super(); + this.registerLogChannel(Constants.mainLogChannelId, nls.localize('mainLog', "Main"), URI.file(join(environmentService.logsPath, `main.log`))); + this.registerLogChannel(Constants.sharedLogChannelId, nls.localize('sharedLog', "Shared"), URI.file(join(environmentService.logsPath, `sharedprocess.log`))); + this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), URI.file(join(environmentService.logsPath, `renderer${environmentService.configuration.windowId}.log`))); + + const registerTelemetryChannel = (level: LogLevel) => { + if (level === LogLevel.Trace && !Registry.as(OutputExt.OutputChannels).getChannel(Constants.telemetryLogChannelId)) { + this.registerLogChannel(Constants.telemetryLogChannelId, nls.localize('telemetryLog', "Telemetry"), URI.file(join(environmentService.logsPath, `telemetry.log`))); + } + }; + registerTelemetryChannel(logService.getLevel()); + logService.onDidChangeLogLevel(registerTelemetryChannel); + + const workbenchActionsRegistry = Registry.as(WorkbenchActionExtensions.WorkbenchActions); + const devCategory = nls.localize('developer', "Developer"); + workbenchActionsRegistry.registerWorkbenchAction(new SyncActionDescriptor(OpenLogsFolderAction, OpenLogsFolderAction.ID, OpenLogsFolderAction.LABEL), 'Developer: Open Logs Folder', devCategory); + } + + private async registerLogChannel(id: string, label: string, file: URI): Promise { + const outputChannelRegistry = Registry.as(OutputExt.OutputChannels); + const exists = await this.fileService.exists(file); + if (exists) { + outputChannelRegistry.registerChannel({ id, label, file, log: true }); + return; + } + + const watcher = this.fileService.watch(dirname(file)); + const disposable = this.fileService.onFileChanges(e => { + if (e.contains(file, FileChangeType.ADDED)) { + watcher.dispose(); + disposable.dispose(); + outputChannelRegistry.registerChannel({ id, label, file, log: true }); + } + }); + } + +} + +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(LogOutputChannels, LifecyclePhase.Restored); \ No newline at end of file diff --git a/src/vs/workbench/contrib/remote/common/remote.contribution.ts b/src/vs/workbench/contrib/remote/common/remote.contribution.ts index 1bfb9d2439a32..f169fda95d143 100644 --- a/src/vs/workbench/contrib/remote/common/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/common/remote.contribution.ts @@ -10,9 +10,12 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { isWeb, OperatingSystem } from 'vs/base/common/platform'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { Schemas } from 'vs/base/common/network'; -import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IRemoteAgentService, RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ILogService } from 'vs/platform/log/common/log'; import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; +import { IOutputChannelRegistry, Extensions as OutputExt, } from 'vs/workbench/contrib/output/common/output'; +import { localize } from 'vs/nls'; +import { joinPath } from 'vs/base/common/resources'; export class LabelContribution implements IWorkbenchContribution { constructor( @@ -54,6 +57,21 @@ class RemoteChannelsContribution implements IWorkbenchContribution { } } +class RemoteLogOutputChannels implements IWorkbenchContribution { + + constructor( + @IRemoteAgentService remoteAgentService: IRemoteAgentService + ) { + remoteAgentService.getEnvironment().then(remoteEnv => { + if (remoteEnv) { + const outputChannelRegistry = Registry.as(OutputExt.OutputChannels); + outputChannelRegistry.registerChannel({ id: 'remoteExtensionLog', label: localize('remoteExtensionLog', "Remote Server"), file: joinPath(remoteEnv.logsPath, `${RemoteExtensionLogFileName}.log`), log: true }); + } + }); + } +} + const workbenchContributionsRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(LabelContribution, LifecyclePhase.Starting); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteChannelsContribution, LifecyclePhase.Starting); +workbenchContributionsRegistry.registerWorkbenchContribution(RemoteLogOutputChannels, LifecyclePhase.Restored); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index ee92df6ca328a..b395f8f4997d8 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -203,6 +203,7 @@ registerSingleton(IPreferencesSearchService, PreferencesSearchService, true); // Logs import 'vs/workbench/contrib/logs/common/logs.contribution'; +import 'vs/workbench/contrib/logs/electron-browser/logs.contribution'; // Quick Open Handlers import 'vs/workbench/contrib/quickopen/browser/quickopen.contribution'; From b8914bcfc753d7149297f6c8a456fb6e1daf6698 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 19 Jun 2019 12:55:47 +0200 Subject: [PATCH 091/364] move install-server --- build/gulpfile.reh.js | 32 ++++++++++++++++++++++++++++++++ build/npm/install-server.js | 15 --------------- package.json | 3 +-- 3 files changed, 33 insertions(+), 17 deletions(-) delete mode 100644 build/npm/install-server.js diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 83eebc9d69d6b..b0e919883c460 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -19,6 +19,8 @@ const untar = require('gulp-untar'); const File = require('vinyl'); const fs = require('fs'); +const cp = require('child_process'); + const REPO_ROOT = path.dirname(__dirname); const noop = () => { return Promise.resolve(); }; @@ -115,3 +117,33 @@ function nodejs(platform, arch) { })) ); } + +function mixinServer(watch) { + const packageJSONPath = path.join(path.dirname(__dirname), 'package.json'); + function exec(cmdLine) { + console.log(cmdLine); + cp.execSync(cmdLine, { stdio: "inherit" }); + } + function checkout() { + const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString()); + exec('git fetch distro'); + exec(`git checkout ${packageJSON['distro']} -- src/vs/server resources/server`); + exec('git reset HEAD src/vs/server resources/server'); + } + checkout(); + if (watch) { + console.log('Enter watch mode (observing package.json)'); + const watcher = fs.watch(packageJSONPath); + watcher.addListener('change', () => { + try { + checkout(); + } catch (e) { + console.log(e); + } + }); + } + return Promise.resolve(); +} + +gulp.task(task.define('mixin-server', () => mixinServer(false))); +gulp.task(task.define('mixin-server-watch', () => mixinServer(true))); diff --git a/build/npm/install-server.js b/build/npm/install-server.js deleted file mode 100644 index ffeec1fa30adf..0000000000000 --- a/build/npm/install-server.js +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -const cp = require('child_process'); - -function exec(cmdLine) { - console.log(cmdLine); - cp.execSync(cmdLine, {stdio: "inherit"}); -} - -exec('git fetch distro'); -exec(`git checkout ${process.env['npm_package_distro']} -- src/vs/server resources/server`); -exec('git reset HEAD src/vs/server resources/server'); \ No newline at end of file diff --git a/package.json b/package.json index 59ec4eafc4f6b..81215e8740c57 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,7 @@ "monaco-compile-check": "tsc -p src/tsconfig.monaco.json --noEmit", "strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization", "web": "node resources/server/bin-dev/code-web.js --port 9888", - "web-selfhost": "node resources/server/bin-dev/code-web.js --port 9777 --selfhost", - "install-server": "node build/npm/install-server.js" + "web-selfhost": "node resources/server/bin-dev/code-web.js --port 9777 --selfhost" }, "dependencies": { "applicationinsights": "1.0.8", From 39d2a648d27cfb3436de2412996df08bec2be08f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 14:31:24 +0200 Subject: [PATCH 092/364] web - unblock running --- src/vs/code/browser/workbench/workbench.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index dc3e933ec7487..6126d1ea3cdf0 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -8,8 +8,8 @@ - + From 63d867d80403f6be290955e71a7b7e05ea414ba8 Mon Sep 17 00:00:00 2001 From: orange4glace Date: Wed, 19 Jun 2019 21:36:30 +0900 Subject: [PATCH 093/364] fix: code convention --- .../files/browser/views/explorerViewer.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 3da1ae98039bf..184916e4ee56c 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -218,8 +218,17 @@ export class FilesRenderer implements ITreeRenderer inputBox.focus(), 100); - inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); + + let isFinishableDisposeEvent = false; + setTimeout(() => { + // Check if disposed + if (!inputBox.inputElement) { + return; + } + inputBox.focus(); + inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); + isFinishableDisposeEvent = true; + }, 0); const done = once(async (success: boolean) => { label.element.style.display = 'none'; @@ -251,8 +260,12 @@ export class FilesRenderer implements ITreeRenderer { - blurDisposable.dispose(); - done(false); + if (isFinishableDisposeEvent) { + done(false); + } + else { + dispose(toDispose); + } }); } From a2a9aeb5f475f470a070025c9aaae45a1c991a1b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 19 Jun 2019 14:54:18 +0200 Subject: [PATCH 094/364] fix #75318 --- src/vs/editor/contrib/documentSymbols/outlineTree.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index 926d6a3da2fd0..dc34e90fcfbdd 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -225,11 +225,11 @@ export class OutlineItemComparator implements ITreeSorter { } else if (a instanceof OutlineElement && b instanceof OutlineElement) { if (this.type === OutlineSortOrder.ByKind) { - return a.symbol.kind - b.symbol.kind || a.symbol.name.localeCompare(b.symbol.name); + return a.symbol.kind - b.symbol.kind || a.symbol.name.localeCompare(b.symbol.name, undefined, { numeric: true }); } else if (this.type === OutlineSortOrder.ByName) { - return a.symbol.name.localeCompare(b.symbol.name) || Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range); + return a.symbol.name.localeCompare(b.symbol.name, undefined, { numeric: true }) || Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range); } else if (this.type === OutlineSortOrder.ByPosition) { - return Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range) || a.symbol.name.localeCompare(b.symbol.name); + return Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range) || a.symbol.name.localeCompare(b.symbol.name, undefined, { numeric: true }); } } return 0; From a6652b5df25afec4f43a4ff1c845a5e1f1f77b91 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 19 Jun 2019 14:56:13 +0200 Subject: [PATCH 095/364] gotoErrorWidget: do not focus the error widget, but use alert to read out message fixes #41356 --- src/vs/editor/contrib/gotoError/gotoErrorWidget.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index 8f2bef9143554..968fa5d44cbf3 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -25,7 +25,7 @@ import { basename } from 'vs/base/common/resources'; import { IAction } from 'vs/base/common/actions'; import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; -import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; +import * as aria from 'vs/base/browser/ui/aria/aria'; import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon'; class MessageWidget { @@ -287,9 +287,7 @@ export class MarkerNavigationWidget extends PeekViewWidget { this.editor.revealPositionInCenter(position, ScrollType.Smooth); - if (this.editor.getConfiguration().accessibilitySupport !== AccessibilitySupport.Disabled) { - this.focus(); - } + aria.alert(marker.message); } updateMarker(marker: IMarker): void { From 912ad66a107488b558f8fef93d224a48cb2990b6 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 19 Jun 2019 14:56:13 +0200 Subject: [PATCH 096/364] fix indent guides in icon exploration --- src/vs/base/browser/ui/tree/media/tree.css | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 03f75d4e6e28e..d194c7d5350e5 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -14,10 +14,15 @@ height: 100%; position: absolute; top: 0; - left: 16px; + left: 14px; pointer-events: none; } +/* TODO @misolori remove before shipping stable */ +body:not([data-exploration="icon-exploration"]) .monaco-tl-indent { + left: 16px; +} + .monaco-tl-indent > svg { overflow: visible; } From 930290cfbe94afa5fef3eb653400b557192f2e85 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 19 Jun 2019 15:12:10 +0200 Subject: [PATCH 097/364] explorero: file actions disablment no longer needed --- .../contrib/files/browser/fileActions.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index f12976ad42cb4..837f66be83b71 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -85,15 +85,10 @@ export class NewFileAction extends Action { static readonly LABEL = nls.localize('createNewFile', "New File"); constructor( - @IExplorerService explorerService: IExplorerService, @ICommandService private commandService: ICommandService ) { super('explorer.newFile', NEW_FILE_LABEL); this.class = 'explorer-action new-file'; - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } run(): Promise { @@ -107,15 +102,10 @@ export class NewFolderAction extends Action { static readonly LABEL = nls.localize('createNewFolder', "New Folder"); constructor( - @IExplorerService explorerService: IExplorerService, @ICommandService private commandService: ICommandService ) { super('explorer.newFolder', NEW_FOLDER_LABEL); this.class = 'explorer-action new-folder'; - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } run(): Promise { @@ -609,10 +599,6 @@ export class CollapseExplorerView extends Action { @IExplorerService readonly explorerService: IExplorerService ) { super(id, label, 'explorer-action collapse-explorer'); - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } run(): Promise { @@ -637,10 +623,6 @@ export class RefreshExplorerView extends Action { @IExplorerService private readonly explorerService: IExplorerService ) { super(id, label, 'explorer-action refresh-explorer'); - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } public run(): Promise { From e8c370eb6c5cdc95107a5fa88e6095a3202b3dc9 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 19 Jun 2019 15:25:23 +0200 Subject: [PATCH 098/364] remove web scripts --- package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index 81215e8740c57..5e48f5b06f36b 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,7 @@ "smoketest": "cd test/smoke && node test/index.js", "download-builtin-extensions": "node build/lib/builtInExtensions.js", "monaco-compile-check": "tsc -p src/tsconfig.monaco.json --noEmit", - "strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization", - "web": "node resources/server/bin-dev/code-web.js --port 9888", - "web-selfhost": "node resources/server/bin-dev/code-web.js --port 9777 --selfhost" + "strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization" }, "dependencies": { "applicationinsights": "1.0.8", From 29bdb65295ab0aa9b848b55f04838f94063d4f92 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 15:36:07 +0200 Subject: [PATCH 099/364] fix missing remote server channels --- src/vs/workbench/workbench.main.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index b395f8f4997d8..3265cab58ce12 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -277,6 +277,7 @@ import { ITaskService } from 'vs/workbench/contrib/tasks/common/taskService'; registerSingleton(ITaskService, TaskService, true); // Remote +import 'vs/workbench/contrib/remote/common/remote.contribution'; import 'vs/workbench/contrib/remote/electron-browser/remote.contribution'; // Emmet From 57044c615aad6d2fe1366f8aa8b08129a8baa3f1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 15:38:38 +0200 Subject: [PATCH 100/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5e48f5b06f36b..93dd6fac19b6e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "42a63f3c8b7d02f13b3af1f2666b293af0951c9a", + "distro": "f664f7661e70234cf4257fa5df73e635a98880a9", "author": { "name": "Microsoft Corporation" }, From c78bc4a4aca6436174c40edd11ef3fb6d1f6fea2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 15:40:08 +0200 Subject: [PATCH 101/364] flaky test (#75772) --- .../terminal/test/electron-browser/terminalConfigHelper.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts index e0110601c8248..3d2cf17654958 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts @@ -16,7 +16,7 @@ suite('Workbench - TerminalConfigHelper', () => { fixture = document.body; }); - test('TerminalConfigHelper - getFont fontFamily', function () { + test.skip('TerminalConfigHelper - getFont fontFamily', function () { const configurationService = new TestConfigurationService(); configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: 'bar' } }); From 87285c4e79e280cdfe141c57e3f9959fbf48b68e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 15:40:52 +0200 Subject: [PATCH 102/364] introduce web user data dir for user data --- src/vs/platform/environment/node/environmentService.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index b4f9e1c2061e2..c021bbb4000ba 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -104,6 +104,9 @@ export class EnvironmentService implements IEnvironmentService { return parseUserDataDir(this._args, process); } + @memoize + get webUserDataHome(): URI { return URI.file(parsePathArg(this._args['web-user-data-dir'], process) || this.userDataPath); } + get appNameLong(): string { return product.nameLong; } get appQuality(): string | undefined { return product.quality; } From 81865ae71155101ed99278bde03f9d9e706744e7 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 19 Jun 2019 15:46:12 +0200 Subject: [PATCH 103/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93dd6fac19b6e..d864657d0964c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "f664f7661e70234cf4257fa5df73e635a98880a9", + "distro": "aae69b0c37c45dcdd6c220116ada3a742c859cfd", "author": { "name": "Microsoft Corporation" }, From b950554a2a773e5392fc96c7c93099aa8682845d Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 19 Jun 2019 16:09:24 +0200 Subject: [PATCH 104/364] debug config manager: first init launches then register listeners --- .../contrib/debug/browser/debugConfigurationManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index af9817c980794..317b77e3e78ff 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -73,8 +73,8 @@ export class ConfigurationManager implements IConfigurationManager { this.adapterDescriptorFactories = []; this.debuggers = []; this.toDispose = []; - this.registerListeners(lifecycleService); this.initLaunches(); + this.registerListeners(lifecycleService); const previousSelectedRoot = this.storageService.get(DEBUG_SELECTED_ROOT, StorageScope.WORKSPACE); const previousSelectedLaunch = this.launches.filter(l => l.uri.toString() === previousSelectedRoot).pop(); this.debugConfigurationTypeContext = CONTEXT_DEBUG_CONFIGURATION_TYPE.bindTo(contextKeyService); From c76027bbf4532815facae5a2df4017d57f4be51a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 19 Jun 2019 16:11:44 +0200 Subject: [PATCH 105/364] pixel perfect indent guides --- src/vs/base/browser/ui/tree/abstractTree.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index fadc69ed298d6..c3527a710b8d0 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -381,12 +381,14 @@ class TreeRenderer implements IListRenderer implements IListRenderer('line', { x1: x, y1: 0, x2: x, y2: height }); + const x = Math.floor((target.depth - i - 1) * this.indent * window.devicePixelRatio) + 2.5; + const line = $.SVG('line', { x1: x, y1: 0, x2: x, y2: virtualHeight }); if (this.activeParentNodes.has(parent)) { addClass(line, 'active'); From 8a0e33ad3dbb75d10e27c4e37aed1c15d4422928 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 16:15:07 +0200 Subject: [PATCH 106/364] web - bring CSP back differently --- src/vs/code/browser/workbench/workbench.html | 36 ++++++++++---------- src/vs/code/browser/workbench/workbench.js | 4 ++- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 6126d1ea3cdf0..fedadf22ee6da 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -1,30 +1,30 @@ + + - - + + - - + - + - - - - - - + + - - + + + - - + + - - + + + + \ No newline at end of file diff --git a/src/vs/code/browser/workbench/workbench.js b/src/vs/code/browser/workbench/workbench.js index 5915d0531cf8b..34f321f90df97 100644 --- a/src/vs/code/browser/workbench/workbench.js +++ b/src/vs/code/browser/workbench/workbench.js @@ -19,6 +19,8 @@ }); require(['vs/workbench/workbench.web.api'], function (api) { - api.create(document.body, JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings'))); + const options = JSON.parse(document.getElementById('vscode-workbench-web-configuration').getAttribute('data-settings')); + + api.create(document.body, options); }); })(); \ No newline at end of file From 5565ddd88c6350f90e1031be4ce0d6089ac73a57 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 19 Jun 2019 15:58:46 +0200 Subject: [PATCH 107/364] update style.textContent instead of calling insertRule, #75061 this change makes style changes visible to the mutation observer --- src/vs/base/browser/dom.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 64fd5661495bb..265d69f85a261 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -804,8 +804,7 @@ export function createCSSRule(selector: string, cssText: string, style: HTMLStyl if (!style || !cssText) { return; } - - (style.sheet).insertRule(selector + '{' + cssText + '}', 0); + style.textContent = `${selector}{${cssText}}\n${style.textContent}`; } export function removeCSSRulesContainingSelector(ruleName: string, style: HTMLStyleElement = getSharedStyleSheet()): void { From 29c09c3c830f4a8ef40564bb19c2b996bcc5a2a2 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 16:16:37 +0200 Subject: [PATCH 108/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d864657d0964c..855edf7282ec9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "aae69b0c37c45dcdd6c220116ada3a742c859cfd", + "distro": "224180ef61f67fc894727cb89068881165b35a0f", "author": { "name": "Microsoft Corporation" }, From 0be038b24dafd06752659dabedba99bc811f2368 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 16:21:49 +0200 Subject: [PATCH 109/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 855edf7282ec9..f4b162d2c4fe7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "224180ef61f67fc894727cb89068881165b35a0f", + "distro": "09333a710f6609d785037c9edce88a4fda48bfb2", "author": { "name": "Microsoft Corporation" }, From b6341520000c2615b9f0cb4aad732216826d0bc4 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 19 Jun 2019 16:42:41 +0200 Subject: [PATCH 110/364] Revert "explorero: file actions disablment no longer needed" This reverts commit 930290cfbe94afa5fef3eb653400b557192f2e85. --- .../contrib/files/browser/fileActions.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index 837f66be83b71..f12976ad42cb4 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -85,10 +85,15 @@ export class NewFileAction extends Action { static readonly LABEL = nls.localize('createNewFile', "New File"); constructor( + @IExplorerService explorerService: IExplorerService, @ICommandService private commandService: ICommandService ) { super('explorer.newFile', NEW_FILE_LABEL); this.class = 'explorer-action new-file'; + this._register(explorerService.onDidChangeEditable(e => { + const elementIsBeingEdited = explorerService.isEditable(e); + this.enabled = !elementIsBeingEdited; + })); } run(): Promise { @@ -102,10 +107,15 @@ export class NewFolderAction extends Action { static readonly LABEL = nls.localize('createNewFolder', "New Folder"); constructor( + @IExplorerService explorerService: IExplorerService, @ICommandService private commandService: ICommandService ) { super('explorer.newFolder', NEW_FOLDER_LABEL); this.class = 'explorer-action new-folder'; + this._register(explorerService.onDidChangeEditable(e => { + const elementIsBeingEdited = explorerService.isEditable(e); + this.enabled = !elementIsBeingEdited; + })); } run(): Promise { @@ -599,6 +609,10 @@ export class CollapseExplorerView extends Action { @IExplorerService readonly explorerService: IExplorerService ) { super(id, label, 'explorer-action collapse-explorer'); + this._register(explorerService.onDidChangeEditable(e => { + const elementIsBeingEdited = explorerService.isEditable(e); + this.enabled = !elementIsBeingEdited; + })); } run(): Promise { @@ -623,6 +637,10 @@ export class RefreshExplorerView extends Action { @IExplorerService private readonly explorerService: IExplorerService ) { super(id, label, 'explorer-action refresh-explorer'); + this._register(explorerService.onDidChangeEditable(e => { + const elementIsBeingEdited = explorerService.isEditable(e); + this.enabled = !elementIsBeingEdited; + })); } public run(): Promise { From a05e05ca19f6e82d0d90c54029a8b76e4ed5896a Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 19 Jun 2019 16:49:10 +0200 Subject: [PATCH 111/364] Revert "Merge pull request #75695 from orange4glace/master" This reverts commit 28ab9ad9fe8db71dc9804985785f041272d9b545, reversing changes made to 912ad66a107488b558f8fef93d224a48cb2990b6. --- .../files/browser/views/explorerViewer.ts | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 184916e4ee56c..76fab05327567 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -218,29 +218,22 @@ export class FilesRenderer implements ITreeRenderer 0 && !stat.isDirectory ? lastDot : value.length }); - let isFinishableDisposeEvent = false; - setTimeout(() => { - // Check if disposed - if (!inputBox.inputElement) { - return; - } - inputBox.focus(); - inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); - isFinishableDisposeEvent = true; - }, 0); - - const done = once(async (success: boolean) => { + const done = once(async (success: boolean, finishEditing: boolean) => { label.element.style.display = 'none'; const value = inputBox.value; dispose(toDispose); container.removeChild(label.element); - // Timeout: once done rendering only then re-render #70902 - setTimeout(() => editableData.onFinish(value, success), 0); + if (finishEditing) { + // Timeout: once done rendering only then re-render #70902 + setTimeout(() => editableData.onFinish(value, success), 0); + } }); const blurDisposable = DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => { - done(inputBox.isInputValid()); + done(inputBox.isInputValid(), true); }); const toDispose = [ @@ -248,10 +241,10 @@ export class FilesRenderer implements ITreeRenderer { if (e.equals(KeyCode.Enter)) { if (inputBox.validate()) { - done(true); + done(true, true); } } else if (e.equals(KeyCode.Escape)) { - done(false); + done(false, true); } }), blurDisposable, @@ -260,12 +253,8 @@ export class FilesRenderer implements ITreeRenderer { - if (isFinishableDisposeEvent) { - done(false); - } - else { - dispose(toDispose); - } + blurDisposable.dispose(); + done(false, false); }); } From 06230bedfe09a143a6e54828be019eb4139a309e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 17:07:40 +0200 Subject: [PATCH 112/364] web - cleanup main --- .../browser/configurationResolverService.ts | 7 +++++-- src/vs/workbench/services/search/common/searchService.ts | 2 ++ src/vs/workbench/workbench.main.ts | 4 +--- src/vs/workbench/workbench.web.main.ts | 9 ++------- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts index c9a8760aa965a..bcf4b31cef937 100644 --- a/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts +++ b/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.ts @@ -19,8 +19,9 @@ import { AbstractVariableResolverService } from 'vs/workbench/services/configura import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput'; import { IQuickInputService, IInputOptions, IQuickPickItem, IPickOptions } from 'vs/platform/quickinput/common/quickInput'; -import { ConfiguredInput } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; +import { ConfiguredInput, IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export abstract class BaseConfigurationResolverService extends AbstractVariableResolverService { @@ -304,4 +305,6 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi ) { super(environmentService.configuration.userEnv, editorService, environmentService, configurationService, commandService, workspaceContextService, quickInputService); } -} \ No newline at end of file +} + +registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); \ No newline at end of file diff --git a/src/vs/workbench/services/search/common/searchService.ts b/src/vs/workbench/services/search/common/searchService.ts index 7051709d15fd5..8c793ca7a8708 100644 --- a/src/vs/workbench/services/search/common/searchService.ts +++ b/src/vs/workbench/services/search/common/searchService.ts @@ -20,6 +20,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { deserializeSearchError, FileMatch, ICachedSearchStats, IFileMatch, IFileQuery, IFileSearchStats, IFolderQuery, IProgressMessage, ISearchComplete, ISearchEngineStats, ISearchProgressItem, ISearchQuery, ISearchResultProvider, ISearchService, ITextQuery, pathIncludedInQuery, QueryType, SearchError, SearchErrorCode, SearchProviderType, isFileMatch, isProgressMessage } from 'vs/workbench/services/search/common/search'; import { addContextToEditorMatches, editorMatchesToTextSearchResults } from 'vs/workbench/services/search/common/searchHelpers'; import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; export class SearchService extends Disposable implements ISearchService { _serviceBrand: any; @@ -421,3 +422,4 @@ export class RemoteSearchService extends SearchService { } } +registerSingleton(ISearchService, RemoteSearchService, true); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 3265cab58ce12..b1130436d6dbb 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -90,8 +90,6 @@ import { IURLService } from 'vs/platform/url/common/url'; import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; -import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; @@ -136,6 +134,7 @@ import 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import 'vs/workbench/services/notification/common/notificationService'; import 'vs/workbench/services/window/electron-browser/windowService'; import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; +import 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); @@ -163,7 +162,6 @@ registerSingleton(IWorkspacesService, WorkspacesService); registerSingleton(IMenubarService, MenubarService); registerSingleton(IURLService, RelayURLService); registerSingleton(ITunnelService, TunnelService, true); -registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); registerSingleton(ICredentialsService, KeytarCredentialsService, true); //#endregion diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index b7c880a010588..2582af5164461 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -89,10 +89,6 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; // import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; // import { ITunnelService } from 'vs/platform/remote/common/tunnel'; // import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; -import { ConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; -import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; -import { ISearchService } from 'vs/workbench/services/search/common/search'; -import { RemoteSearchService } from 'vs/workbench/services/search/common/searchService'; import 'vs/platform/dialogs/browser/dialogService'; import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; // import 'vs/workbench/services/integrity/node/integrityService'; @@ -101,7 +97,7 @@ import 'vs/workbench/services/textMate/browser/textMateService'; // import 'vs/workbench/services/workspace/electron-browser/workspaceEditingService'; // import 'vs/workbench/services/extensions/electron-browser/inactiveExtensionUrlHandler'; import 'vs/workbench/services/decorations/browser/decorationsService'; -// import 'vs/workbench/services/search/node/searchService'; +import 'vs/workbench/services/search/common/searchService'; import 'vs/workbench/services/progress/browser/progressService'; import 'vs/workbench/services/editor/browser/codeEditorService'; // import 'vs/workbench/services/extensions/electron-browser/extensionHostDebugService'; @@ -134,6 +130,7 @@ import 'vs/workbench/services/label/common/labelService'; import 'vs/workbench/services/notification/common/notificationService'; // import 'vs/workbench/services/window/electron-browser/windowService'; // import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; +import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; import 'vs/workbench/browser/web.simpleservices'; @@ -162,9 +159,7 @@ registerSingleton(ILifecycleService, BrowserLifecycleService); // registerSingleton(IWorkspacesService, WorkspacesService); // registerSingleton(IMenubarService, MenubarService); // registerSingleton(IURLService, RelayURLService); -registerSingleton(ISearchService, RemoteSearchService, true); registerSingleton(IContextMenuService, ContextMenuService); -registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true); //#endregion From 771328d713bdab1cdea2dea60bf2cfd1cf7b66a1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 19 Jun 2019 17:17:52 +0200 Subject: [PATCH 113/364] :lipstick: main files --- src/vs/platform/dialogs/browser/dialogService.ts | 3 --- src/vs/workbench/workbench.main.ts | 3 +++ src/vs/workbench/workbench.web.main.ts | 13 ++++++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/vs/platform/dialogs/browser/dialogService.ts b/src/vs/platform/dialogs/browser/dialogService.ts index d5cc82af88431..5a906768029b2 100644 --- a/src/vs/platform/dialogs/browser/dialogService.ts +++ b/src/vs/platform/dialogs/browser/dialogService.ts @@ -9,7 +9,6 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { ILogService } from 'vs/platform/log/common/log'; import Severity from 'vs/base/common/severity'; import { Dialog } from 'vs/base/browser/ui/dialog/dialog'; -import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachDialogStyler } from 'vs/platform/theme/common/styler'; import { DisposableStore } from 'vs/base/common/lifecycle'; @@ -93,5 +92,3 @@ export class DialogService implements IDialogService { return choice; } } - -registerSingleton(IDialogService, DialogService, true); diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index b1130436d6dbb..a6c31adbe640c 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -71,6 +71,8 @@ import { IRequestService } from 'vs/platform/request/node/request'; import { RequestService } from 'vs/platform/request/electron-browser/requestService'; import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { DialogService } from 'vs/platform/dialogs/browser/dialogService'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; @@ -136,6 +138,7 @@ import 'vs/workbench/services/window/electron-browser/windowService'; import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; import 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; +registerSingleton(IDialogService, DialogService, true); registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); registerSingleton(IOpenerService, OpenerService, true); diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 2582af5164461..7bdf1ac3687fc 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -62,14 +62,15 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { BrowserAccessibilityService } from 'vs/platform/accessibility/common/accessibilityService'; -import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; +// import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService'; // import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; // import { IRequestService } from 'vs/platform/request/node/request'; // import { RequestService } from 'vs/platform/request/electron-browser/requestService'; import { BrowserLifecycleService } from 'vs/platform/lifecycle/browser/lifecycleService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; +import { DialogService } from 'vs/platform/dialogs/browser/dialogService'; // import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; // import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; // import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; @@ -89,7 +90,8 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; // import { RelayURLService } from 'vs/platform/url/electron-browser/urlService'; // import { ITunnelService } from 'vs/platform/remote/common/tunnel'; // import { TunnelService } from 'vs/workbench/services/remote/node/tunnelService'; -import 'vs/platform/dialogs/browser/dialogService'; +// import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; +// import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; import 'vs/workbench/services/bulkEdit/browser/bulkEditService'; // import 'vs/workbench/services/integrity/node/integrityService'; import 'vs/workbench/services/keybinding/common/keybindingEditing'; @@ -131,9 +133,12 @@ import 'vs/workbench/services/notification/common/notificationService'; // import 'vs/workbench/services/window/electron-browser/windowService'; // import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; import 'vs/workbench/services/configurationResolver/browser/configurationResolverService'; +import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; import 'vs/workbench/browser/web.simpleservices'; +registerSingleton(IDialogService, DialogService, true); registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); registerSingleton(IOpenerService, OpenerService, true); @@ -159,6 +164,8 @@ registerSingleton(ILifecycleService, BrowserLifecycleService); // registerSingleton(IWorkspacesService, WorkspacesService); // registerSingleton(IMenubarService, MenubarService); // registerSingleton(IURLService, RelayURLService); +// registerSingleton(ITunnelService, TunnelService, true); +// registerSingleton(ICredentialsService, KeytarCredentialsService, true); registerSingleton(IContextMenuService, ContextMenuService); //#endregion From 79f5f1a48de44c372e8ec6b35a5d8b4a205df1dd Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 19 Jun 2019 17:18:43 +0200 Subject: [PATCH 114/364] fixes #75773 --- src/vs/base/browser/ui/tree/media/tree.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index d194c7d5350e5..564d5505e4163 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -18,6 +18,10 @@ pointer-events: none; } +.hide-arrows .monaco-tl-indent { + left: 10px; +} + /* TODO @misolori remove before shipping stable */ body:not([data-exploration="icon-exploration"]) .monaco-tl-indent { left: 16px; From 8f3ba7e312e236b6f935978477b8de269bd7b71d Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 10:17:10 -0700 Subject: [PATCH 115/364] keyboard layout picker --- .../browser/keyboardLayoutPicker.ts | 56 +++++++++-- .../environment/browser/environmentService.ts | 3 +- .../keybinding/browser/keybindingService.ts | 5 +- .../browser/keyboardLayoutProvider.ts | 39 +++++++- .../browser/keyboardLayoutService.ts | 93 +++++++++++++++---- .../keybinding/common/keymapService.ts | 24 +++++ 6 files changed, 182 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index a5ad35624d07a..6536b626fa743 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService, areKeyboardLayoutsEqual } from 'vs/workbench/services/keybinding/common/keymapService'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; @@ -17,6 +17,11 @@ import { isWeb, isMacintosh, isWindows } from 'vs/base/common/platform'; import { QuickPickInput, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { IEditor } from 'vs/workbench/common/editor'; export class KeyboardLayoutPickerContribution extends Disposable implements IWorkbenchContribution { private readonly pickerElement = this._register(new MutableDisposable()); @@ -46,7 +51,8 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor let layoutInfo = (layout).text || (layout).lang || (layout).model; this.pickerElement.value.update({ - text: `Layout: ${layoutInfo}` + text: `Layout: ${layoutInfo}`, + command: KEYBOARD_LAYOUT_OPEN_PICKER }); } })); @@ -61,12 +67,23 @@ export class KeyboardLayoutPickerAction extends Action { static readonly ID = KEYBOARD_LAYOUT_OPEN_PICKER; static readonly LABEL = nls.localize('keyboard.chooseLayout', "Change keyboard layout"); + private static DEFAULT_CONTENT: string = [ + `// ${nls.localize('displayLanguage', 'Defines the keyboard layout used in VS Code in the browser environment.')}`, + `// ${nls.localize('doc', 'See {0} for how to generate keyboard layout information.', 'https://go.microsoft.com/fwlink/?LinkId=761051')}`, + ``, + `// Once you have the keyboard layout info, please paste it below.`, + '\n' + ].join('\n'); + constructor( actionId: string, actionLabel: string, + @IFileService private readonly fileService: IFileService, @IQuickInputService private readonly quickInputService: IQuickInputService, @IKeymapService private readonly keymapService: IKeymapService, - @IConfigurationService private readonly configurationService: IConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IEditorService private readonly editorService: IEditorService ) { super(actionId, actionLabel); @@ -75,11 +92,16 @@ export class KeyboardLayoutPickerAction extends Action { async run(): Promise { let layouts = this.keymapService.getAllKeyboardLayouts(); + let currentLayout = this.keymapService.getCurrentKeyboardLayout(); + let layoutConfig = this.configurationService.getValue('keyboard.layout'); + let isAutoDetect = layoutConfig === 'autodetect'; const picks: QuickPickInput[] = layouts.map(layout => { + const picked = !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout); return { label: (layout).text || (layout).lang || (layout).layout, - description: (layout).id || undefined + description: ((layout).id || '') + (picked ? ' (Current selection)' : ''), + picked: !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout) }; }); @@ -88,13 +110,15 @@ export class KeyboardLayoutPickerAction extends Action { picks.unshift({ type: 'separator', label: nls.localize('layoutPicks', "Keyboard Layouts ({0})", platform) }); } - let configureKeyboardLayout: IQuickPickItem = { label: nls.localize('configureKeyboardLayout', "Configure KeyboardLayout") }; + let configureKeyboardLayout: IQuickPickItem = { label: nls.localize('configureKeyboardLayout', "Configure Keyboard Layout") }; picks.unshift(configureKeyboardLayout); // Offer to "Auto Detect" const autoDetectMode: IQuickPickItem = { - label: nls.localize('autoDetect', "Auto Detect") + label: nls.localize('autoDetect', "Auto Detect"), + description: isAutoDetect ? `(Current: ${(currentLayout).text || (currentLayout).lang || (currentLayout).layout})` : undefined, + picked: isAutoDetect ? true : undefined }; picks.unshift(autoDetectMode); @@ -111,7 +135,23 @@ export class KeyboardLayoutPickerAction extends Action { } if (pick === configureKeyboardLayout) { - return; + const file = this.environmentService.keyboardLayoutResource; + + await this.fileService.resolve(file).then(undefined, (error) => { + return this.fileService.createFile(file, VSBuffer.fromString(KeyboardLayoutPickerAction.DEFAULT_CONTENT)); + }).then((stat): Promise | null => { + if (!stat) { + return null; + } + return this.editorService.openEditor({ + resource: stat.resource, + mode: 'jsonc' + }); + }, (error) => { + throw new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", file.toString(), error)); + }); + + return Promise.resolve(); } this.configurationService.updateValue('keyboard.layout', pick.label); @@ -119,4 +159,4 @@ export class KeyboardLayoutPickerAction extends Action { } const registry = Registry.as(ActionExtensions.WorkbenchActions); -registry.registerWorkbenchAction(new SyncActionDescriptor(KeyboardLayoutPickerAction, KeyboardLayoutPickerAction.ID, KeyboardLayoutPickerAction.LABEL, { }), 'Change Language Mode'); +registry.registerWorkbenchAction(new SyncActionDescriptor(KeyboardLayoutPickerAction, KeyboardLayoutPickerAction.ID, KeyboardLayoutPickerAction.LABEL, {}), 'Change Language Mode'); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index a865a77a2038c..d224fa7383bd7 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -58,7 +58,6 @@ export class BrowserWindowConfiguration implements IWindowConfiguration { } export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { - _serviceBrand: ServiceIdentifier; readonly configuration: IWindowConfiguration = new BrowserWindowConfiguration(); @@ -73,6 +72,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { this.appSettingsHome = joinPath(URI.revive(configuration.userDataUri), 'User'); this.settingsResource = joinPath(this.appSettingsHome, 'settings.json'); this.keybindingsResource = joinPath(this.appSettingsHome, 'keybindings.json'); + this.keyboardLayoutResource = joinPath(this.appSettingsHome, 'keyboardLayout.json'); this.logsPath = '/web/logs'; @@ -97,6 +97,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { appSettingsHome: URI; settingsResource: URI; keybindingsResource: URI; + keyboardLayoutResource: URI; machineSettingsHome: URI; machineSettingsResource: URI; settingsSearchBuildId?: number; diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index 56591386c3f7d..9a5369924c4ea 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -46,7 +46,6 @@ import * as objects from 'vs/base/common/objects'; import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapService'; import { getDispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { isArray } from 'vs/base/common/types'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; interface ContributedKeyBinding { @@ -149,7 +148,6 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { private _keyboardMapper: IKeyboardMapper; private _cachedResolver: KeybindingResolver | null; private userKeybindings: UserKeybindings; - private _statusBarDisposable: IDisposable = Disposable.None; constructor( @IContextKeyService contextKeyService: IContextKeyService, @@ -161,8 +159,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { @IWindowService private readonly windowService: IWindowService, @IExtensionService extensionService: IExtensionService, @IFileService fileService: IFileService, - @IKeymapService private readonly keymapService: IKeymapService, - @IInstantiationService private readonly instantiationService: IInstantiationService + @IKeymapService private readonly keymapService: IKeymapService ) { super(contextKeyService, commandService, telemetryService, notificationService); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts index 7ad610563783f..8057f5180b3d8 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts @@ -67,17 +67,26 @@ interface ISerializedMapping { export class KeyboardLayoutInfo { value: IKeyboardMapping; + isUserKeyboardLayout: boolean; - constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping) { + constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping, isUserKeyboardLayout?: boolean) { this.value = deserializeMapping(keyboardMapping); + this.isUserKeyboardLayout = !!isUserKeyboardLayout; } - static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IKeyboardMapping): KeyboardLayoutInfo { - let keyboardLayoutInfo = new KeyboardLayoutInfo(layout, [], {}); + static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IKeyboardMapping, isUserKeyboardLayout?: boolean): KeyboardLayoutInfo { + let keyboardLayoutInfo = new KeyboardLayoutInfo(layout, [], {}, true); keyboardLayoutInfo.value = value; return keyboardLayoutInfo; } + update(other: KeyboardLayoutInfo) { + this.layout = other.layout; + this.secondaryLayouts = other.secondaryLayouts; + this.value = other.value; + this.isUserKeyboardLayout = other.isUserKeyboardLayout; + } + fuzzyEqual(other: IKeyboardMapping): boolean { for (let key in other) { if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { @@ -265,6 +274,19 @@ export class KeyboardLayoutProvider { this._mru.unshift(this._active); } + setActive2(layout: KeyboardLayoutInfo) { + this._active = layout; + + const index = this._mru.indexOf(this._active); + + if (index === 0) { + return; + } + + this._mru.splice(index, 1); + this._mru.unshift(this._active); + } + getMatchedKeyboardLayout(keymap: IKeyboardMapping): KeyboardLayoutInfo | null { // TODO go through mru list instead of _layoutInfos for (let i = 0; i < this._mru.length; i++) { @@ -276,7 +298,14 @@ export class KeyboardLayoutProvider { return null; } - getKeyboardLayouts(): IKeyboardLayoutInfo[] { - return this._layoutInfos.map(info => info.layout); + getKeyboardLayouts(): KeyboardLayoutInfo[] { + return this._layoutInfos; + } + + removeKeyboardLayout(layout: KeyboardLayoutInfo): void { + let index = this._mru.indexOf(layout); + this._mru.splice(index, 1); + index = this._layoutInfos.indexOf(layout); + this._layoutInfos.splice(index, 1); } } diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts index 940d5a126a74a..8bdc394d035fd 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts @@ -6,11 +6,11 @@ import * as nls from 'vs/nls'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, toDisposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, IWindowsKeyboardLayoutInfo, IMacKeyboardLayoutInfo, ILinuxKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; -import { OS, OperatingSystem, isMacintosh, isWindows } from 'vs/base/common/platform'; +import { OS, OperatingSystem, isMacintosh, isWindows, isLinux } from 'vs/base/common/platform'; import { WindowsKeyboardMapper } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; @@ -49,7 +49,7 @@ export class BrowserKeyboardMapperFactory { import('vs/workbench/services/keybinding/browser/keyboardlayouts/layout.contribution.' + platform).then(() => { this._initialized = true; - this._onKeyboardLayoutChanged(); + this.onKeyboardLayoutChanged(); }); if ((navigator).keyboard && (navigator).keyboard.addEventListener) { @@ -60,13 +60,13 @@ export class BrowserKeyboardMapperFactory { return; } - this._onKeyboardLayoutChanged(); + this.onKeyboardLayoutChanged(); }); }); } } - private _onKeyboardLayoutChanged(): void { + public onKeyboardLayoutChanged(): void { this._updateKeyboardLayoutAsync(this._initialized); } @@ -109,7 +109,7 @@ export class BrowserKeyboardMapperFactory { } public getAllKeyboardLayouts(): IKeyboardLayoutInfo[] { - return KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts(); + return KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts().map(info => info.layout); } public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { @@ -152,7 +152,7 @@ export class BrowserKeyboardMapperFactory { return; } - this._onKeyboardLayoutChanged(); + this.onKeyboardLayoutChanged(); }); }, 350); } @@ -187,6 +187,36 @@ export class BrowserKeyboardMapperFactory { return this._rawMapping; } + public setKeyboardLayout(layoutName: string) { + let allKeyboardLayouts = KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts(); + let matchedLayouts: KeyboardLayoutInfo[] = []; + if (isWindows) { + matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).name === layoutName); + } + + if (isMacintosh) { + // todo, probably we should use layout.id? + matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).lang === layoutName); + } + + if (isLinux) { + // todo, probably we should use layout.id? + matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).layout === layoutName); + } + + if (matchedLayouts.length > 0) { + KeyboardLayoutProvider.INSTANCE.setActive2(matchedLayouts[0]); + + let currentKeyboardLayout = KeyboardLayoutProvider.INSTANCE.activeKeyboardLayout; + + if (currentKeyboardLayout) { + this._setKeyboardData(currentKeyboardLayout.layout, currentKeyboardLayout.value); + + return; + } + } + } + private _setKeyboardData(layoutInfo: IKeyboardLayoutInfo, rawMapping: IKeyboardMapping): void { this._layoutInfo = layoutInfo; this._initialized = true; @@ -343,6 +373,12 @@ class UserKeyboardLayout extends Disposable { })); } + async initialize(): Promise { + const exists = await this.fileService.exists(this.keyboardLayoutResource); + this.onResourceExists(exists); + await this.reload(); + } + private async reload(): Promise { const existing = this._keyboardLayout; try { @@ -350,7 +386,7 @@ class UserKeyboardLayout extends Disposable { const value = parse(content.value.toString()); const layoutInfo = value.layout; const mappings = value.rawMapping; - this._keyboardLayout = KeyboardLayoutInfo.createKeyboardLayoutFromDebugInfo(layoutInfo, mappings); + this._keyboardLayout = KeyboardLayoutInfo.createKeyboardLayoutFromDebugInfo(layoutInfo, mappings, true); } catch (e) { this._keyboardLayout = null; } @@ -427,15 +463,14 @@ class BrowserKeymapService extends Disposable implements IKeymapService { @IFileService fileService: IFileService, ) { super(); - - this._userKeyboardLayout = new UserKeyboardLayout(environmentService.keyboardLayoutResource, fileService); const keyboardConfig = configurationService.getValue<{ layout: string }>('keyboard'); const layout = keyboardConfig.layout; - if (layout === 'autodetect') { + if (!layout || layout === 'autodetect') { this.registerKeyboardListener(); } else { // set keyboard layout + BrowserKeyboardMapperFactory.INSTANCE.setKeyboardLayout(layout); } this._register(configurationService.onDidChangeConfiguration(e => { @@ -445,19 +480,40 @@ class BrowserKeymapService extends Disposable implements IKeymapService { if (layout === 'autodetect') { this.registerKeyboardListener(); - // trigger an update - console.log('auto'); + BrowserKeyboardMapperFactory.INSTANCE.onKeyboardLayoutChanged(); } else { - this.layoutChangeListener.clear(); - // set current layout - console.log(layout); + BrowserKeyboardMapperFactory.INSTANCE.setKeyboardLayout(layout); } } })); + + this._userKeyboardLayout = new UserKeyboardLayout(environmentService.keyboardLayoutResource, fileService); + this._userKeyboardLayout.initialize(); + + if (this._userKeyboardLayout.keyboardLayout) { + KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + } + + this._register(this._userKeyboardLayout.onDidChange(() => { + let userKeyboardLayouts = KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts().filter(layout => layout.isUserKeyboardLayout); + + if (userKeyboardLayouts.length) { + if (this._userKeyboardLayout.keyboardLayout) { + userKeyboardLayouts[0].update(this._userKeyboardLayout.keyboardLayout); + } else { + KeyboardLayoutProvider.INSTANCE.removeKeyboardLayout(userKeyboardLayouts[0]); + } + } else { + if (this._userKeyboardLayout.keyboardLayout) { + KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + } + } + + // TODO: trigger keymap update + })); } registerKeyboardListener() { - this.layoutChangeListener.clear(); this.layoutChangeListener.value = BrowserKeyboardMapperFactory.INSTANCE.onDidChangeKeyboardMapper(() => { this._onDidChangeKeyboardMapper.fire(); }); @@ -472,9 +528,6 @@ class BrowserKeymapService extends Disposable implements IKeymapService { } public getAllKeyboardLayouts(): IKeyboardLayoutInfo[] { - if (this._userKeyboardLayout.keyboardLayout) { - return [this._userKeyboardLayout.keyboardLayout.layout, ...BrowserKeyboardMapperFactory.INSTANCE.getAllKeyboardLayouts()]; - } return BrowserKeyboardMapperFactory.INSTANCE.getAllKeyboardLayouts(); } diff --git a/src/vs/workbench/services/keybinding/common/keymapService.ts b/src/vs/workbench/services/keybinding/common/keymapService.ts index ee5b8acab8e68..19a73c5b7d654 100644 --- a/src/vs/workbench/services/keybinding/common/keymapService.ts +++ b/src/vs/workbench/services/keybinding/common/keymapService.ts @@ -98,3 +98,27 @@ export interface IKeymapService { getRawKeyboardMapping(): IKeyboardMapping | null; validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void; } + +export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeyboardLayoutInfo | null): boolean { + if (!a || !b) { + return false; + } + + if ((a).name && (b).name && (a).name === (b).name) { + return true; + } + + if ((a).id && (b).id && (a).id === (b).id) { + return true; + } + + if ((a).model && + (b).model && + (a).model === (b).model && + (a).layout === (b).layout + ) { + return true; + } + + return false; +} From 9481d84b0d5318aa02fe9da81f816e4cc6b8d201 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Wed, 19 Jun 2019 10:35:53 -0700 Subject: [PATCH 116/364] Fix #75784, only target specific icons for exploration --- src/vs/workbench/browser/media/icons.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/media/icons.css b/src/vs/workbench/browser/media/icons.css index 1d000db29a08b..05465d73aa370 100644 --- a/src/vs/workbench/browser/media/icons.css +++ b/src/vs/workbench/browser/media/icons.css @@ -67,8 +67,13 @@ body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .t body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Source Control: Git actions"] .icon[data-title="git.refresh"], body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Debug actions"] .icon, body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label^="Extensions"] .icon, -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title^="git."], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label, +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.unstage"], +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.stage"], +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.openChange"], +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.clean"], +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.cleanAll"], +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.stageAll"], +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.unstageAll"], body[data-exploration^="icon-exploration"] .monaco-workbench .part > .content > .debug-viewlet .actions .action-label.icon, body[data-exploration^="icon-exploration"] .monaco-workbench .debug-toolbar .drag-area, body[data-exploration^="icon-exploration"] .monaco-workbench .debug-toolbar .action-label, From 40bbb20c6006e619e47f29c337ff62a9585b18bd Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Jun 2019 11:03:14 -0700 Subject: [PATCH 117/364] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f4b162d2c4fe7..6916b4088ec60 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "09333a710f6609d785037c9edce88a4fda48bfb2", + "distro": "26125d2b5b10bac3b3de09f4ee565ea4d5c1c7bc", "author": { "name": "Microsoft Corporation" }, From 3ccdd1e63d4819349903e17019264b954e56db44 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 11:55:53 -0700 Subject: [PATCH 118/364] Add (Local) to the local terminal title Part of microsoft/vscode-remote-release#730 --- src/vs/workbench/contrib/terminal/node/terminalRemote.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/node/terminalRemote.ts b/src/vs/workbench/contrib/terminal/node/terminalRemote.ts index 9b849a12833ff..e264cdfdd5d5d 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalRemote.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalRemote.ts @@ -34,6 +34,15 @@ export class CreateNewLocalTerminalAction extends Action { if (!instance) { return Promise.resolve(undefined); } + + // Append (Local) to the first title that comes back, the title will then become static + const disposable = instance.onTitleChanged(() => { + if (instance.title && instance.title.trim().length > 0) { + disposable.dispose(); + instance.setTitle(`${instance.title} (Local)`, false); + } + }); + this.terminalService.setActiveInstance(instance); return this.terminalService.showPanel(true); } From a24d186db848a902e38ca2556096583ad443e067 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 12:01:06 -0700 Subject: [PATCH 119/364] refactor, move keyboard layout provider into keymapper factory --- .../browser/keyboardLayoutPicker.ts | 41 ++- .../browser/keyboardLayoutProvider.ts | 311 ------------------ .../browser/keyboardLayouts/_.contribution.ts | 23 ++ .../browser/keyboardLayouts/cz.win.ts | 5 +- .../browser/keyboardLayouts/de-swiss.win.ts | 5 +- .../browser/keyboardLayouts/de.darwin.ts | 5 +- .../browser/keyboardLayouts/de.linux.ts | 5 +- .../browser/keyboardLayouts/de.win.ts | 5 +- .../browser/keyboardLayouts/dk.win.ts | 5 +- .../browser/keyboardLayouts/en-belgian.win.ts | 5 +- .../browser/keyboardLayouts/en-ext.darwin.ts | 5 +- .../browser/keyboardLayouts/en-in.win.ts | 5 +- .../browser/keyboardLayouts/en-intl.darwin.ts | 5 +- .../browser/keyboardLayouts/en-intl.win.ts | 5 +- .../browser/keyboardLayouts/en-uk.darwin.ts | 5 +- .../browser/keyboardLayouts/en-uk.win.ts | 5 +- .../browser/keyboardLayouts/en.darwin.ts | 5 +- .../browser/keyboardLayouts/en.linux.ts | 5 +- .../browser/keyboardLayouts/en.win.ts | 5 +- .../browser/keyboardLayouts/es-latin.win.ts | 5 +- .../browser/keyboardLayouts/es.darwin.ts | 5 +- .../browser/keyboardLayouts/es.linux.ts | 5 +- .../browser/keyboardLayouts/es.win.ts | 5 +- .../browser/keyboardLayouts/fr.darwin.ts | 5 +- .../browser/keyboardLayouts/fr.linux.ts | 5 +- .../browser/keyboardLayouts/fr.win.ts | 5 +- .../browser/keyboardLayouts/hu.win.ts | 5 +- .../browser/keyboardLayouts/it.darwin.ts | 5 +- .../browser/keyboardLayouts/it.win.ts | 5 +- .../keyboardLayouts/jp-roman.darwin.ts | 5 +- .../browser/keyboardLayouts/jp.darwin.ts | 5 +- .../browser/keyboardLayouts/ko.darwin.ts | 5 +- .../browser/keyboardLayouts/no.win.ts | 5 +- .../browser/keyboardLayouts/pl.darwin.ts | 5 +- .../browser/keyboardLayouts/pl.win.ts | 5 +- .../browser/keyboardLayouts/pt-br.win.ts | 5 +- .../browser/keyboardLayouts/pt.darwin.ts | 5 +- .../browser/keyboardLayouts/pt.win.ts | 5 +- .../browser/keyboardLayouts/ru.darwin.ts | 5 +- .../browser/keyboardLayouts/ru.linux.ts | 5 +- .../browser/keyboardLayouts/ru.win.ts | 5 +- .../browser/keyboardLayouts/sv.darwin.ts | 5 +- .../browser/keyboardLayouts/sv.win.ts | 5 +- .../browser/keyboardLayouts/thai.win.ts | 5 +- .../browser/keyboardLayouts/tr.win.ts | 5 +- .../browser/keyboardLayouts/zh-hans.darwin.ts | 5 +- ...boardLayoutService.ts => keymapService.ts} | 300 ++++++++++------- .../services/keybinding/common/keymapInfo.ts | 110 +++++++ src/vs/workbench/workbench.web.main.ts | 2 +- 49 files changed, 469 insertions(+), 533 deletions(-) delete mode 100644 src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts create mode 100644 src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts rename src/vs/workbench/services/keybinding/browser/{keyboardLayoutService.ts => keymapService.ts} (78%) create mode 100644 src/vs/workbench/services/keybinding/common/keymapInfo.ts diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 6536b626fa743..b05c5974a984a 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -33,27 +33,40 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor super(); let layout = this.keymapService.getCurrentKeyboardLayout(); - let layoutInfo = (layout).text || (layout).lang || (layout).model; - this.pickerElement.value = this.statusbarService.addEntry( - { - text: `Layout: ${layoutInfo}`, - // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), - command: KEYBOARD_LAYOUT_OPEN_PICKER - }, - 'status.editor.screenReaderMode', - nls.localize('status.editor.screenReaderMode', "Screen Reader Mode"), - StatusbarAlignment.RIGHT - ); + if (layout) { + let layoutInfo = (layout).text || (layout).lang || (layout).model; + this.pickerElement.value = this.statusbarService.addEntry( + { + text: `Layout: ${layoutInfo}`, + // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), + command: KEYBOARD_LAYOUT_OPEN_PICKER + }, + 'status.editor.screenReaderMode', + nls.localize('status.editor.screenReaderMode', "Screen Reader Mode"), + StatusbarAlignment.RIGHT + ); + } this._register(keymapService.onDidChangeKeyboardMapper(() => { - if (this.pickerElement.value) { - let layout = this.keymapService.getCurrentKeyboardLayout(); - let layoutInfo = (layout).text || (layout).lang || (layout).model; + let layout = this.keymapService.getCurrentKeyboardLayout(); + let layoutInfo = (layout).text || (layout).lang || (layout).model; + if (this.pickerElement.value) { this.pickerElement.value.update({ text: `Layout: ${layoutInfo}`, command: KEYBOARD_LAYOUT_OPEN_PICKER }); + } else { + this.pickerElement.value = this.statusbarService.addEntry( + { + text: `Layout: ${layoutInfo}`, + // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), + command: KEYBOARD_LAYOUT_OPEN_PICKER + }, + 'status.editor.screenReaderMode', + nls.localize('status.editor.screenReaderMode', "Screen Reader Mode"), + StatusbarAlignment.RIGHT + ); } })); } diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts deleted file mode 100644 index 8057f5180b3d8..0000000000000 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayoutProvider.ts +++ /dev/null @@ -1,311 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapService'; -import { isWindows } from 'vs/base/common/platform'; - -function deserializeMapping(serializedMapping: ISerializedMapping) { - let mapping = serializedMapping; - - let ret = {}; - for (let key in mapping) { - let result: (string | number)[] = mapping[key]; - if (result.length) { - let value = result[0]; - let withShift = result[1]; - let withAltGr = result[2]; - let withShiftAltGr = result[3]; - let mask = Number(result[4]); - let vkey = result.length === 6 ? result[5] : undefined; - ret[key] = { - 'value': value, - 'vkey': vkey, - 'withShift': withShift, - 'withAltGr': withAltGr, - 'withShiftAltGr': withShiftAltGr, - 'valueIsDeadKey': (mask & 1) > 0, - 'withShiftIsDeadKey': (mask & 2) > 0, - 'withAltGrIsDeadKey': (mask & 4) > 0, - 'withShiftAltGrIsDeadKey': (mask & 8) > 0 - }; - } else { - ret[key] = { - 'value': '', - 'valueIsDeadKey': false, - 'withShift': '', - 'withShiftIsDeadKey': false, - 'withAltGr': '', - 'withAltGrIsDeadKey': false, - 'withShiftAltGr': '', - 'withShiftAltGrIsDeadKey': false - }; - } - } - - return ret; -} - -interface IKeyboardMapping { - [key: string]: { - value: string, - withShift: string; - withAltGr: string; - withShiftAltGr: string; - valueIsDeadKey?: boolean; - withShiftIsDeadKey?: boolean; - withAltGrIsDeadKey?: boolean; - withShiftAltGrIsDeadKey?: boolean; - - }; -} - -interface ISerializedMapping { - [key: string]: (string | number)[]; -} - -export class KeyboardLayoutInfo { - value: IKeyboardMapping; - isUserKeyboardLayout: boolean; - - constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping, isUserKeyboardLayout?: boolean) { - this.value = deserializeMapping(keyboardMapping); - this.isUserKeyboardLayout = !!isUserKeyboardLayout; - } - - static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IKeyboardMapping, isUserKeyboardLayout?: boolean): KeyboardLayoutInfo { - let keyboardLayoutInfo = new KeyboardLayoutInfo(layout, [], {}, true); - keyboardLayoutInfo.value = value; - return keyboardLayoutInfo; - } - - update(other: KeyboardLayoutInfo) { - this.layout = other.layout; - this.secondaryLayouts = other.secondaryLayouts; - this.value = other.value; - this.isUserKeyboardLayout = other.isUserKeyboardLayout; - } - - fuzzyEqual(other: IKeyboardMapping): boolean { - for (let key in other) { - if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { - // keymap from Chromium is probably wrong. - continue; - } - if (this.value[key] === undefined) { - return false; - } - - let currentMapping = this.value[key]; - let otherMapping = other[key]; - - if (currentMapping.value !== otherMapping.value) { - return false; - } - } - - return true; - } -} - -export const EN_US = new KeyboardLayoutInfo( - { id: 'com.apple.keylayout.US', lang: 'en' }, - [], - { - KeyA: ['a', 'A', 'å', 'Å', 0], - KeyB: ['b', 'B', '∫', 'ı', 0], - KeyC: ['c', 'C', 'ç', 'Ç', 0], - KeyD: ['d', 'D', '∂', 'Î', 0], - KeyE: ['e', 'E', '´', '´', 4], - KeyF: ['f', 'F', 'ƒ', 'Ï', 0], - KeyG: ['g', 'G', '©', '˝', 0], - KeyH: ['h', 'H', '˙', 'Ó', 0], - KeyI: ['i', 'I', 'ˆ', 'ˆ', 4], - KeyJ: ['j', 'J', '∆', 'Ô', 0], - KeyK: ['k', 'K', '˚', '', 0], - KeyL: ['l', 'L', '¬', 'Ò', 0], - KeyM: ['m', 'M', 'µ', 'Â', 0], - KeyN: ['n', 'N', '˜', '˜', 4], - KeyO: ['o', 'O', 'ø', 'Ø', 0], - KeyP: ['p', 'P', 'π', '∏', 0], - KeyQ: ['q', 'Q', 'œ', 'Œ', 0], - KeyR: ['r', 'R', '®', '‰', 0], - KeyS: ['s', 'S', 'ß', 'Í', 0], - KeyT: ['t', 'T', '†', 'ˇ', 0], - KeyU: ['u', 'U', '¨', '¨', 4], - KeyV: ['v', 'V', '√', '◊', 0], - KeyW: ['w', 'W', '∑', '„', 0], - KeyX: ['x', 'X', '≈', '˛', 0], - KeyY: ['y', 'Y', '¥', 'Á', 0], - KeyZ: ['z', 'Z', 'Ω', '¸', 0], - Digit1: ['1', '!', '¡', '⁄', 0], - Digit2: ['2', '@', '™', '€', 0], - Digit3: ['3', '#', '£', '‹', 0], - Digit4: ['4', '$', '¢', '›', 0], - Digit5: ['5', '%', '∞', 'fi', 0], - Digit6: ['6', '^', '§', 'fl', 0], - Digit7: ['7', '&', '¶', '‡', 0], - Digit8: ['8', '*', '•', '°', 0], - Digit9: ['9', '(', 'ª', '·', 0], - Digit0: ['0', ')', 'º', '‚', 0], - Enter: [], - Escape: [], - Backspace: [], - Tab: [], - Space: [' ', ' ', ' ', ' ', 0], - Minus: ['-', '_', '–', '—', 0], - Equal: ['=', '+', '≠', '±', 0], - BracketLeft: ['[', '{', '“', '”', 0], - BracketRight: [']', '}', '‘', '’', 0], - Backslash: ['\\', '|', '«', '»', 0], - Semicolon: [';', ':', '…', 'Ú', 0], - Quote: ['\'', '"', 'æ', 'Æ', 0], - Backquote: ['`', '~', '`', '`', 4], - Comma: [',', '<', '≤', '¯', 0], - Period: ['.', '>', '≥', '˘', 0], - Slash: ['/', '?', '÷', '¿', 0], - CapsLock: [], - F1: [], - F2: [], - F3: [], - F4: [], - F5: [], - F6: [], - F7: [], - F8: [], - F9: [], - F10: [], - F11: [], - F12: [], - Insert: [], - Home: [], - PageUp: [], - Delete: [], - End: [], - PageDown: [], - ArrowRight: [], - ArrowLeft: [], - ArrowDown: [], - ArrowUp: [], - NumLock: [], - NumpadDivide: ['/', '/', '/', '/', 0], - NumpadMultiply: ['*', '*', '*', '*', 0], - NumpadSubtract: ['-', '-', '-', '-', 0], - NumpadAdd: ['+', '+', '+', '+', 0], - NumpadEnter: [], - Numpad1: ['1', '1', '1', '1', 0], - Numpad2: ['2', '2', '2', '2', 0], - Numpad3: ['3', '3', '3', '3', 0], - Numpad4: ['4', '4', '4', '4', 0], - Numpad5: ['5', '5', '5', '5', 0], - Numpad6: ['6', '6', '6', '6', 0], - Numpad7: ['7', '7', '7', '7', 0], - Numpad8: ['8', '8', '8', '8', 0], - Numpad9: ['9', '9', '9', '9', 0], - Numpad0: ['0', '0', '0', '0', 0], - NumpadDecimal: ['.', '.', '.', '.', 0], - IntlBackslash: ['§', '±', '§', '±', 0], - ContextMenu: [], - NumpadEqual: ['=', '=', '=', '=', 0], - F13: [], - F14: [], - F15: [], - F16: [], - F17: [], - F18: [], - F19: [], - F20: [], - AudioVolumeMute: [], - AudioVolumeUp: ['', '=', '', '=', 0], - AudioVolumeDown: [], - NumpadComma: [], - IntlRo: [], - KanaMode: [], - IntlYen: [], - ControlLeft: [], - ShiftLeft: [], - AltLeft: [], - MetaLeft: [], - ControlRight: [], - ShiftRight: [], - AltRight: [], - MetaRight: [] - } -); - -export class KeyboardLayoutProvider { - public static readonly INSTANCE: KeyboardLayoutProvider = new KeyboardLayoutProvider(); - - private _layoutInfos: KeyboardLayoutInfo[] = []; - private _mru: KeyboardLayoutInfo[] = []; - private _active: KeyboardLayoutInfo | null; - - private constructor() { - this._active = null; - } - - registerKeyboardLayout(layout: KeyboardLayoutInfo) { - this._layoutInfos.push(layout); - this._mru = this._layoutInfos; - } - - get activeKeyboardLayout() { - return this._active; - } - - isActive(keymap: IKeyboardMapping) { - return this._active && this._active.fuzzyEqual(keymap); - } - - setActive(keymap: IKeyboardMapping) { - this._active = this.getMatchedKeyboardLayout(keymap); - - if (!this._active) { - return; - } - const index = this._mru.indexOf(this._active); - - if (index === 0) { - return; - } - - this._mru.splice(index, 1); - this._mru.unshift(this._active); - } - - setActive2(layout: KeyboardLayoutInfo) { - this._active = layout; - - const index = this._mru.indexOf(this._active); - - if (index === 0) { - return; - } - - this._mru.splice(index, 1); - this._mru.unshift(this._active); - } - - getMatchedKeyboardLayout(keymap: IKeyboardMapping): KeyboardLayoutInfo | null { - // TODO go through mru list instead of _layoutInfos - for (let i = 0; i < this._mru.length; i++) { - if (this._mru[i].fuzzyEqual(keymap)) { - return this._mru[i]; - } - } - - return null; - } - - getKeyboardLayouts(): KeyboardLayoutInfo[] { - return this._layoutInfos; - } - - removeKeyboardLayout(layout: KeyboardLayoutInfo): void { - let index = this._mru.indexOf(layout); - this._mru.splice(index, 1); - index = this._layoutInfos.indexOf(layout); - this._layoutInfos.splice(index, 1); - } -} diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts new file mode 100644 index 0000000000000..846b6023774ce --- /dev/null +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; + +export class KeyboardLayoutContribution { + public static readonly INSTANCE: KeyboardLayoutContribution = new KeyboardLayoutContribution(); + + private _layoutInfos: KeymapInfo[] = []; + + get layoutInfos() { + return this._layoutInfos; + } + + private constructor() { + } + + registerKeyboardLayout(layout: KeymapInfo) { + this._layoutInfos.push(layout); + } +} \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts index 1908441eceb8d..8d560875c613f 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000405', id: '', text: 'Czech' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts index 44d82a33db5cd..b7d6467220a49 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000807', id: '', text: 'Swiss German' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts index aa796ffa23665..573f80946640e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.German', lang: 'de' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts index 780c2785ac4f9..2f7f85af3caec 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { model: 'pc104', layout: 'de', variant: '', options: '', rules: 'base' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts index 5f304096a0eb7..0bf3c61618ecd 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000407', id: '', text: 'German' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts index f75d21328dfd9..34f7f3103a73d 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000406', id: '', text: 'Danish' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts index 19b8f5543038b..6e5cae52518da 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000813', id: '', text: 'Belgian (Period)' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts index 3409ffa246918..91bc1741acfcc 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.USExtended', lang: 'en' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts index 7cd020c80877b..d3ad3786dcb3b 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00004009', id: '', text: 'India' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts index 8b740fd65d8b1..cdbcf3bcfd2cd 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.USInternational-PC', lang: 'en' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts index 019d09d7f67e9..ce5ade144e244 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00020409', id: '0001', text: 'United States-International' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts index 444c61e111ac4..e50f88303976e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.British', lang: 'en' }, [], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts index f8b26f6493af6..d3aa6995fb91c 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000809', id: '', text: 'United Kingdom' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts index 54b5f4f135bda..fabf23b5864cb 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.US', lang: 'en' }, [ { id: 'com.apple.keylayout.ABC', lang: 'en' }, diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts index 6c56ce8e50dfe..ae5e356006add 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { model: 'pc105', layout: 'us', variant: '', options: '', rules: 'evdev' }, [ { model: 'pc105', layout: 'cn', variant: '', options: '', rules: 'evdev' }, diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts index cfb7709c62714..cb7e8e42da293 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000409', id: '', text: 'US' }, [ { name: '00000804', id: '', text: 'Chinese (Simplified) - US Keyboard' }, diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts index b7a0251226f77..6234c4542804d 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000080A', id: '', text: 'Latin American' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts index 8f78ab6957d5f..ecc0004d0780b 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.Spanish-ISO', lang: 'es' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts index 7d522fa9eb060..1b4f4d9485856 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { model: 'pc105', layout: 'es', variant: '', options: '', rules: 'evdev' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts index 7902f93b24b3f..8fea58dc8727f 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000040A', id: '', text: 'Spanish' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts index b1c4f4e95dc6c..6b47127cec66f 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.French', lang: 'fr' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts index 683a59a9b8e72..7c857332595ce 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { model: 'pc104', layout: 'fr', variant: '', options: '', rules: 'base' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts index 6f3e58821607e..b056c38ff2dc9 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000040C', id: '', text: 'French' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts index fb069ab561b9a..ebcce4786fdc4 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000040E', id: '', text: 'Hungarian' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts index 4d1b13922e5c0..8cb9dc8f995c8 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.Italian-Pro', lang: 'it' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts index 88de00a2ccc65..1b0636f02ab16 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000410', id: '', text: 'Italian' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts index e0efe49090fcb..8f90af0bea967 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.google.inputmethod.Japanese.Roman', lang: 'en' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts index d50fcfb98b926..a48e202b4fb81 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts index 683a0620dd490..d79920103d62a 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.inputmethod.Korean.2SetKorean', lang: 'ko' }, [], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts index da7134a551613..7183b0fbe9fca 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000414', id: '', text: 'Norwegian' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts index 7d97909583d61..75bac351170c7 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.PolishPro', lang: 'pl' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts index 8d91f5cf72a71..9d0576fc4f291 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000415', id: '', text: 'Polish (Programmers)' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts index 5007c43b7d30c..b5886ffc968bb 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000416', id: '', text: 'Portuguese (Brazilian ABNT)' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts index 6f5356ddb8f7d..9a0baec47d2a7 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.Brazilian-Pro', lang: 'pt' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts index 74dfa547d9436..2d1c72c89b965 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000816', id: '', text: 'Portuguese' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts index 7a68e2536bb46..afecb02810dec 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.Russian', lang: 'ru' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts index a1203ca287041..c086909149a44 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { model: 'pc104', layout: 'ru', variant: ',', options: '', rules: 'base' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts index cfc3ac1631f5e..dfe753aacb070 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '00000419', id: '', text: 'Russian' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts index 512d940e43700..e5b57ab30a3c7 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.Swedish-Pro', lang: 'sv' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts index 74f52703c994a..729d9a13bb083 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000041D', id: '', text: 'Swedish' }, [ { name: '0000040B', id: '', text: 'Finnish' } diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts index 36a05f22e417c..013b7ac64f7dd 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000041E', id: '', text: 'Thai Kedmanee' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts index 9708d7e6622c4..058ef5592ae51 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout((new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( { name: '0000041F', id: '', text: 'Turkish Q' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts index 30d7246fa0d12..cf8bfbf0ac67b 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts @@ -3,9 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(new KeyboardLayoutInfo( +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.inputmethod.SCIM.ITABC', lang: 'zh-Hans' }, [], { diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts similarity index 78% rename from src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts rename to src/vs/workbench/services/keybinding/browser/keymapService.ts index 8bdc394d035fd..bd005db83b85f 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -17,7 +17,6 @@ import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; import { KeyCodeUtils, KeyCode } from 'vs/base/common/keyCodes'; import { IMacLinuxKeyboardMapping, MacLinuxKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { KeyboardLayoutProvider, KeyboardLayoutInfo } from 'vs/workbench/services/keybinding/browser/keyboardLayoutProvider'; import { URI } from 'vs/base/common/uri'; import { IFileService, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -29,25 +28,58 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; +import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; export class BrowserKeyboardMapperFactory { public static readonly INSTANCE = new BrowserKeyboardMapperFactory(); - private _layoutInfo: IKeyboardLayoutInfo | null; - private _rawMapping: IKeyboardMapping | null; - private _keyboardMapper: IKeyboardMapper | null; + // keyboard mapper private _initialized: boolean; + private _keyboardMapper: IKeyboardMapper | null; private readonly _onDidChangeKeyboardMapper = new Emitter(); public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; + // keymap infos + private _keymapInfos: KeymapInfo[]; + private _mru: KeymapInfo[]; + private _activeKeymapInfo: KeymapInfo | null; + + get keymapInfos(): KeymapInfo[] { + return this._keymapInfos; + } + + get activeKeyboardLayout(): IKeyboardLayoutInfo | null { + if (!this._initialized) { + return null; + } + + return this._activeKeymapInfo && this._activeKeymapInfo.layout; + } + + get activeKeyMapping(): IKeyboardMapping | null { + if (!this._initialized) { + return null; + } + + return this._activeKeymapInfo && this._activeKeymapInfo.mapping; + } + + get keyboardLayouts(): IKeyboardLayoutInfo[] { + return this._keymapInfos.map(keymapInfo => keymapInfo.layout); + } + private constructor() { - this._layoutInfo = null; - this._rawMapping = null; this._keyboardMapper = null; this._initialized = false; + this._keymapInfos = []; + this._mru = []; + this._activeKeymapInfo = null; const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; - import('vs/workbench/services/keybinding/browser/keyboardlayouts/layout.contribution.' + platform).then(() => { + import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then(() => { + this._keymapInfos.push(...KeyboardLayoutContribution.INSTANCE.layoutInfos); + this._mru = this._keymapInfos; this._initialized = true; this.onKeyboardLayoutChanged(); }); @@ -55,8 +87,8 @@ export class BrowserKeyboardMapperFactory { if ((navigator).keyboard && (navigator).keyboard.addEventListener) { (navigator).keyboard.addEventListener!('layoutchange', () => { // Update user keyboard map settings - this.getBrowserKeyMap().then((keymap: IKeyboardMapping) => { - if (KeyboardLayoutProvider.INSTANCE.isActive(keymap)) { + this._getBrowserKeyMapping().then((mapping: IKeyboardMapping) => { + if (this.isKeyMappingActive(mapping)) { return; } @@ -66,6 +98,62 @@ export class BrowserKeyboardMapperFactory { } } + registerKeyboardLayout(layout: KeymapInfo) { + this._keymapInfos.push(layout); + this._mru = this._keymapInfos; + } + + removeKeyboardLayout(layout: KeymapInfo): void { + let index = this._mru.indexOf(layout); + this._mru.splice(index, 1); + index = this._keymapInfos.indexOf(layout); + this._keymapInfos.splice(index, 1); + } + + getMatchedKeymapInfo(keyMapping: IKeyboardMapping): KeymapInfo | null { + for (let i = 0; i < this._mru.length; i++) { + if (this._mru[i].fuzzyEqual(keyMapping)) { + return this._mru[i]; + } + } + + return null; + } + + isKeyMappingActive(keymap: IKeyboardMapping) { + return this._activeKeymapInfo && this._activeKeymapInfo.fuzzyEqual(keymap); + } + + setActiveKeyMapping(keymap: IKeyboardMapping) { + this._activeKeymapInfo = this.getMatchedKeymapInfo(keymap); + + if (!this._activeKeymapInfo) { + return; + } + + const index = this._mru.indexOf(this._activeKeymapInfo); + + this._mru.splice(index, 1); + this._mru.unshift(this._activeKeymapInfo); + + this._setKeyboardData(this._activeKeymapInfo); + } + + setActiveKeymapInfo(keymapInfo: KeymapInfo) { + this._activeKeymapInfo = keymapInfo; + + const index = this._mru.indexOf(this._activeKeymapInfo); + + if (index === 0) { + return; + } + + this._mru.splice(index, 1); + this._mru.unshift(this._activeKeymapInfo); + + this._setKeyboardData(this._activeKeymapInfo); + } + public onKeyboardLayoutChanged(): void { this._updateKeyboardLayoutAsync(this._initialized); } @@ -75,17 +163,12 @@ export class BrowserKeyboardMapperFactory { return; } - this.getBrowserKeyMap().then(keyMap => { + this._getBrowserKeyMapping().then(keyMap => { // might be false positive - if (KeyboardLayoutProvider.INSTANCE.isActive(keyMap)) { + if (this.isKeyMappingActive(keyMap)) { return; } - KeyboardLayoutProvider.INSTANCE.setActive(keyMap); - let currentKeyboardLayout = KeyboardLayoutProvider.INSTANCE.activeKeyboardLayout; - - if (currentKeyboardLayout) { - this._setKeyboardData(currentKeyboardLayout.layout, keyMap); - } + this.setActiveKeyMapping(keyMap); }); } @@ -101,17 +184,6 @@ export class BrowserKeyboardMapperFactory { } - public getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null { - if (!this._initialized) { - return null; - } - return this._layoutInfo; - } - - public getAllKeyboardLayouts(): IKeyboardLayoutInfo[] { - return KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts().map(info => info.layout); - } - public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { if (!this._initialized) { return; @@ -126,18 +198,75 @@ export class BrowserKeyboardMapperFactory { this._updateKeyboardLayoutAsync(true); } + public setKeyboardLayout(layoutName: string) { + let allKeyboardLayouts = this.keymapInfos; + let matchedLayouts: KeymapInfo[] = []; + if (isWindows) { + matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).name === layoutName); + } + + if (isMacintosh) { + // todo, probably we should use layout.id? + matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).lang === layoutName); + } + + if (isLinux) { + // todo, probably we should use layout.id? + matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).layout === layoutName); + } + + if (matchedLayouts.length > 0) { + this.setActiveKeymapInfo(matchedLayouts[0]); + } + } + + private _setKeyboardData(keymapInfo: KeymapInfo): void { + this._initialized = true; + + this._keyboardMapper = new CachedKeyboardMapper(BrowserKeyboardMapperFactory._createKeyboardMapper(keymapInfo.mapping)); + this._onDidChangeKeyboardMapper.fire(); + } + + private static _isUSStandard(rawMapping: IKeyboardMapping): boolean { + for (let key in rawMapping) { + let str = rawMapping[key].value; + let keyCode = KeyCodeUtils.fromString(str); + let usKeyCode = US_SCANCODE_MAP[key]; + + if (keyCode !== usKeyCode) { + return false; + } + + } + return true; + } + + private static _createKeyboardMapper(rawMapping: IKeyboardMapping): IKeyboardMapper { + const isUSStandard = BrowserKeyboardMapperFactory._isUSStandard(rawMapping); + if (OS === OperatingSystem.Windows) { + return new WindowsKeyboardMapper(isUSStandard, rawMapping); + } + if (Object.keys(rawMapping).length === 0) { + // Looks like reading the mappings failed (most likely Mac + Japanese/Chinese keyboard layouts) + return new MacLinuxFallbackKeyboardMapper(OS); + } + + return new MacLinuxKeyboardMapper(isUSStandard, rawMapping, OS); + } + + //#region Browser API private _validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): boolean { if (!this._initialized) { return true; } const standardKeyboardEvent = keyboardEvent as StandardKeyboardEvent; - const currentKeymap = KeyboardLayoutProvider.INSTANCE.activeKeyboardLayout; + const currentKeymap = this._activeKeymapInfo; if (!currentKeymap) { return true; } - const mapping = currentKeymap.value[standardKeyboardEvent.code]; + const mapping = currentKeymap.mapping[standardKeyboardEvent.code]; if (!mapping) { return false; @@ -147,8 +276,8 @@ export class BrowserKeyboardMapperFactory { // we don't undetstand if (keyboardEvent.ctrlKey || keyboardEvent.metaKey) { setTimeout(() => { - this.getBrowserKeyMap().then((keymap: IKeyboardMapping) => { - if (KeyboardLayoutProvider.INSTANCE.isActive(keymap)) { + this._getBrowserKeyMapping().then((keymap: IKeyboardMapping) => { + if (this.isKeyMappingActive(keymap)) { return; } @@ -180,79 +309,7 @@ export class BrowserKeyboardMapperFactory { return true; } - public getRawKeyboardMapping(): IKeyboardMapping | null { - if (!this._initialized) { - return null; - } - return this._rawMapping; - } - - public setKeyboardLayout(layoutName: string) { - let allKeyboardLayouts = KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts(); - let matchedLayouts: KeyboardLayoutInfo[] = []; - if (isWindows) { - matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).name === layoutName); - } - - if (isMacintosh) { - // todo, probably we should use layout.id? - matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).lang === layoutName); - } - - if (isLinux) { - // todo, probably we should use layout.id? - matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).layout === layoutName); - } - - if (matchedLayouts.length > 0) { - KeyboardLayoutProvider.INSTANCE.setActive2(matchedLayouts[0]); - - let currentKeyboardLayout = KeyboardLayoutProvider.INSTANCE.activeKeyboardLayout; - - if (currentKeyboardLayout) { - this._setKeyboardData(currentKeyboardLayout.layout, currentKeyboardLayout.value); - - return; - } - } - } - - private _setKeyboardData(layoutInfo: IKeyboardLayoutInfo, rawMapping: IKeyboardMapping): void { - this._layoutInfo = layoutInfo; - this._initialized = true; - this._rawMapping = rawMapping; - this._keyboardMapper = new CachedKeyboardMapper(BrowserKeyboardMapperFactory._createKeyboardMapper(this._layoutInfo, this._rawMapping)); - this._onDidChangeKeyboardMapper.fire(); - } - - private static _isUSStandard(rawMapping: IKeyboardMapping): boolean { - for (let key in rawMapping) { - let str = rawMapping[key].value; - let keyCode = KeyCodeUtils.fromString(str); - let usKeyCode = US_SCANCODE_MAP[key]; - - if (keyCode !== usKeyCode) { - return false; - } - - } - return true; - } - - private static _createKeyboardMapper(layoutInfo: IKeyboardLayoutInfo, rawMapping: IKeyboardMapping): IKeyboardMapper { - const isUSStandard = BrowserKeyboardMapperFactory._isUSStandard(rawMapping); - if (OS === OperatingSystem.Windows) { - return new WindowsKeyboardMapper(isUSStandard, rawMapping); - } - if (Object.keys(rawMapping).length === 0) { - // Looks like reading the mappings failed (most likely Mac + Japanese/Chinese keyboard layouts) - return new MacLinuxFallbackKeyboardMapper(OS); - } - - return new MacLinuxKeyboardMapper(isUSStandard, rawMapping, OS); - } - - async getBrowserKeyMap() { + private async _getBrowserKeyMapping() { if ((navigator as any).keyboard) { try { return (navigator as any).keyboard.getLayoutMap().then((e: any) => { @@ -266,10 +323,10 @@ export class BrowserKeyboardMapperFactory { }; } - const matchedKeyboardLayout = KeyboardLayoutProvider.INSTANCE.getMatchedKeyboardLayout(ret); + const matchedKeyboardLayout = this.getMatchedKeymapInfo(ret); if (matchedKeyboardLayout) { - return matchedKeyboardLayout.value; + return matchedKeyboardLayout.mapping; } return {}; @@ -281,8 +338,9 @@ export class BrowserKeyboardMapperFactory { return {}; } -} + //#endregion +} export const US_SCANCODE_MAP: { [str: string]: KeyCode; } = {}; @@ -349,8 +407,8 @@ class UserKeyboardLayout extends Disposable { private fileWatcherDisposable: IDisposable = Disposable.None; private directoryWatcherDisposable: IDisposable = Disposable.None; - private _keyboardLayout: KeyboardLayoutInfo | null; - get keyboardLayout(): KeyboardLayoutInfo | null { return this._keyboardLayout; } + private _keyboardLayout: KeymapInfo | null; + get keyboardLayout(): KeymapInfo | null { return this._keyboardLayout; } constructor( private readonly keyboardLayoutResource: URI, @@ -386,7 +444,7 @@ class UserKeyboardLayout extends Disposable { const value = parse(content.value.toString()); const layoutInfo = value.layout; const mappings = value.rawMapping; - this._keyboardLayout = KeyboardLayoutInfo.createKeyboardLayoutFromDebugInfo(layoutInfo, mappings, true); + this._keyboardLayout = KeymapInfo.createKeyboardLayoutFromDebugInfo(layoutInfo, mappings, true); } catch (e) { this._keyboardLayout = null; } @@ -466,9 +524,9 @@ class BrowserKeymapService extends Disposable implements IKeymapService { const keyboardConfig = configurationService.getValue<{ layout: string }>('keyboard'); const layout = keyboardConfig.layout; - if (!layout || layout === 'autodetect') { - this.registerKeyboardListener(); - } else { + this.registerKeyboardListener(); + + if (layout && layout !== 'autodetect') { // set keyboard layout BrowserKeyboardMapperFactory.INSTANCE.setKeyboardLayout(layout); } @@ -491,21 +549,21 @@ class BrowserKeymapService extends Disposable implements IKeymapService { this._userKeyboardLayout.initialize(); if (this._userKeyboardLayout.keyboardLayout) { - KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + BrowserKeyboardMapperFactory.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); } this._register(this._userKeyboardLayout.onDidChange(() => { - let userKeyboardLayouts = KeyboardLayoutProvider.INSTANCE.getKeyboardLayouts().filter(layout => layout.isUserKeyboardLayout); + let userKeyboardLayouts = BrowserKeyboardMapperFactory.INSTANCE.keymapInfos.filter(layout => layout.isUserKeyboardLayout); if (userKeyboardLayouts.length) { if (this._userKeyboardLayout.keyboardLayout) { userKeyboardLayouts[0].update(this._userKeyboardLayout.keyboardLayout); } else { - KeyboardLayoutProvider.INSTANCE.removeKeyboardLayout(userKeyboardLayouts[0]); + BrowserKeyboardMapperFactory.INSTANCE.removeKeyboardLayout(userKeyboardLayouts[0]); } } else { if (this._userKeyboardLayout.keyboardLayout) { - KeyboardLayoutProvider.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + BrowserKeyboardMapperFactory.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); } } @@ -524,15 +582,15 @@ class BrowserKeymapService extends Disposable implements IKeymapService { } public getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null { - return BrowserKeyboardMapperFactory.INSTANCE.getCurrentKeyboardLayout(); + return BrowserKeyboardMapperFactory.INSTANCE.activeKeyboardLayout; } public getAllKeyboardLayouts(): IKeyboardLayoutInfo[] { - return BrowserKeyboardMapperFactory.INSTANCE.getAllKeyboardLayouts(); + return BrowserKeyboardMapperFactory.INSTANCE.keyboardLayouts; } public getRawKeyboardMapping(): IKeyboardMapping | null { - return BrowserKeyboardMapperFactory.INSTANCE.getRawKeyboardMapping(); + return BrowserKeyboardMapperFactory.INSTANCE.activeKeyMapping; } public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts new file mode 100644 index 0000000000000..7d2665d006d97 --- /dev/null +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapService'; +import { isWindows } from 'vs/base/common/platform'; + +function deserializeMapping(serializedMapping: ISerializedMapping) { + let mapping = serializedMapping; + + let ret = {}; + for (let key in mapping) { + let result: (string | number)[] = mapping[key]; + if (result.length) { + let value = result[0]; + let withShift = result[1]; + let withAltGr = result[2]; + let withShiftAltGr = result[3]; + let mask = Number(result[4]); + let vkey = result.length === 6 ? result[5] : undefined; + ret[key] = { + 'value': value, + 'vkey': vkey, + 'withShift': withShift, + 'withAltGr': withAltGr, + 'withShiftAltGr': withShiftAltGr, + 'valueIsDeadKey': (mask & 1) > 0, + 'withShiftIsDeadKey': (mask & 2) > 0, + 'withAltGrIsDeadKey': (mask & 4) > 0, + 'withShiftAltGrIsDeadKey': (mask & 8) > 0 + }; + } else { + ret[key] = { + 'value': '', + 'valueIsDeadKey': false, + 'withShift': '', + 'withShiftIsDeadKey': false, + 'withAltGr': '', + 'withAltGrIsDeadKey': false, + 'withShiftAltGr': '', + 'withShiftAltGrIsDeadKey': false + }; + } + } + + return ret; +} + +interface IKeyboardMapping { + [key: string]: { + value: string, + withShift: string; + withAltGr: string; + withShiftAltGr: string; + valueIsDeadKey?: boolean; + withShiftIsDeadKey?: boolean; + withAltGrIsDeadKey?: boolean; + withShiftAltGrIsDeadKey?: boolean; + + }; +} + +interface ISerializedMapping { + [key: string]: (string | number)[]; +} + +export class KeymapInfo { + mapping: IKeyboardMapping; + isUserKeyboardLayout: boolean; + + constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping, isUserKeyboardLayout?: boolean) { + this.mapping = deserializeMapping(keyboardMapping); + this.isUserKeyboardLayout = !!isUserKeyboardLayout; + } + + static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IKeyboardMapping, isUserKeyboardLayout?: boolean): KeymapInfo { + let keyboardLayoutInfo = new KeymapInfo(layout, [], {}, true); + keyboardLayoutInfo.mapping = value; + return keyboardLayoutInfo; + } + + update(other: KeymapInfo) { + this.layout = other.layout; + this.secondaryLayouts = other.secondaryLayouts; + this.mapping = other.mapping; + this.isUserKeyboardLayout = other.isUserKeyboardLayout; + } + + fuzzyEqual(other: IKeyboardMapping): boolean { + for (let key in other) { + if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { + // keymap from Chromium is probably wrong. + continue; + } + if (this.mapping[key] === undefined) { + return false; + } + + let currentMapping = this.mapping[key]; + let otherMapping = other[key]; + + if (currentMapping.value !== otherMapping.value) { + return false; + } + } + + return true; + } +} diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 47ce9781da68c..30e1a0f9daae3 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -118,7 +118,7 @@ import 'vs/workbench/services/editor/browser/editorService'; import 'vs/workbench/services/history/browser/history'; import 'vs/workbench/services/activity/browser/activityService'; import 'vs/workbench/browser/parts/views/views'; -import 'vs/workbench/services/keybinding/browser/keyboardLayoutService'; +import 'vs/workbench/services/keybinding/browser/keymapService'; import 'vs/workbench/services/keybinding/browser/keybindingService'; import 'vs/workbench/services/untitled/common/untitledEditorService'; import 'vs/workbench/services/textfile/common/textResourcePropertiesService'; From 8c08a1e523cc10d9608159ca39f53203e8bbc90f Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 12:06:14 -0700 Subject: [PATCH 120/364] linux case senstivity --- .../services/keybinding/browser/keyboardLayoutService.ts | 2 +- .../browser/keyboardLayouts/layout.contribution.linux.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts index 4f2b427641cf6..7d6bb3dbefee0 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayoutService.ts @@ -36,7 +36,7 @@ export class BrowserKeyboardMapperFactory { const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; - import('vs/workbench/services/keybinding/browser/keyboardlayouts/layout.contribution.' + platform).then(() => { + import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then(() => { this._initialized = true; this._onKeyboardLayoutChanged(); }); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts index a0181a659421d..b1aeb2eafd5b7 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts @@ -7,4 +7,4 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux'; -import 'vs/workbench/services/keybinding/browser/keyboardLayouts/fu.linux'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux'; From 3c698386915e5bd1636256d9ff1a996a74521cfb Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 12:07:12 -0700 Subject: [PATCH 121/364] no warnings anymore --- .../services/keybinding/browser/keybindingService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index 74610ab901e00..fdb6f43db9bb4 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -366,31 +366,31 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService { } if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode === KeyCode.KEY_W) { - console.warn('Ctrl/Cmd+W keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + // console.warn('Ctrl/Cmd+W keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); return true; } if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode === KeyCode.KEY_N) { - console.warn('Ctrl/Cmd+N keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + // console.warn('Ctrl/Cmd+N keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); return true; } if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode === KeyCode.KEY_T) { - console.warn('Ctrl/Cmd+T keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + // console.warn('Ctrl/Cmd+T keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); return true; } if ((partModifiersMask & modifiersMask) === (KeyMod.CtrlCmd | KeyMod.Alt) && (part.keyCode === KeyCode.LeftArrow || part.keyCode === KeyCode.RightArrow)) { - console.warn('Ctrl/Cmd+Arrow keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + // console.warn('Ctrl/Cmd+Arrow keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); return true; } if ((partModifiersMask & modifiersMask) === KeyMod.CtrlCmd && part.keyCode >= KeyCode.KEY_0 && part.keyCode <= KeyCode.KEY_9) { - console.warn('Ctrl/Cmd+Num keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); + // console.warn('Ctrl/Cmd+Num keybindings should not be used by default in web. Offender: ', kb.getHashCode(), ' for ', commandId); return true; } From a4e9376c185c794e66afa3811f08a75b48e6e131 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 12:23:09 -0700 Subject: [PATCH 122/364] Re-enable test and split it up Cannot reproduce the failure locally, additionally it was a timeout but it's not an async test... Fixes #75772 --- .../terminalConfigHelper.test.ts | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts index 3d2cf17654958..f1984496f23eb 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalConfigHelper.test.ts @@ -16,27 +16,38 @@ suite('Workbench - TerminalConfigHelper', () => { fixture = document.body; }); - test.skip('TerminalConfigHelper - getFont fontFamily', function () { + test('TerminalConfigHelper - getFont fontFamily', function () { const configurationService = new TestConfigurationService(); configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: 'bar' } }); - - let configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); + const configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontFamily, 'bar', 'terminal.integrated.fontFamily should be selected over editor.fontFamily'); + }); + test('TerminalConfigHelper - getFont fontFamily (Linux Fedora)', function () { + const configurationService = new TestConfigurationService(); + configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } }); - - // Recreate config helper as onDidChangeConfiguration isn't implemented in TestConfigurationService - configHelper = new TerminalConfigHelper(LinuxDistro.Fedora, configurationService, null!, null!, null!); + const configHelper = new TerminalConfigHelper(LinuxDistro.Fedora, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontFamily, '\'DejaVu Sans Mono\', monospace', 'Fedora should have its font overridden when terminal.integrated.fontFamily not set'); + }); - configHelper = new TerminalConfigHelper(LinuxDistro.Ubuntu, configurationService, null!, null!, null!); + test('TerminalConfigHelper - getFont fontFamily (Linux Ubuntu)', function () { + const configurationService = new TestConfigurationService(); + configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); + configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } }); + const configHelper = new TerminalConfigHelper(LinuxDistro.Ubuntu, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontFamily, '\'Ubuntu Mono\', monospace', 'Ubuntu should have its font overridden when terminal.integrated.fontFamily not set'); + }); - configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); + test('TerminalConfigHelper - getFont fontFamily (Linux Unknown)', function () { + const configurationService = new TestConfigurationService(); + configurationService.setUserConfiguration('editor', { fontFamily: 'foo' }); + configurationService.setUserConfiguration('terminal', { integrated: { fontFamily: null } }); + const configHelper = new TerminalConfigHelper(LinuxDistro.Unknown, configurationService, null!, null!, null!); configHelper.panelContainer = fixture; assert.equal(configHelper.getFont().fontFamily, 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set'); }); From c62e57fed146f1a6d79e6e30e99d3455da64ec1c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 12:31:59 -0700 Subject: [PATCH 123/364] Remove unneeded isWeb check electron-browser/ will already prevent this --- .../terminal/electron-browser/terminalNativeService.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts index 12406462f4403..d8591bc61728b 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalNativeService.ts @@ -15,7 +15,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { registerRemoteContributions } from 'vs/workbench/contrib/terminal/node/terminalRemote'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -import { isWeb } from 'vs/base/common/platform'; export class TerminalNativeService implements ITerminalNativeService { public _serviceBrand: any; @@ -35,11 +34,9 @@ export class TerminalNativeService implements ITerminalNativeService { ipc.on('vscode:openFiles', (_event: any, request: IOpenFileRequest) => this._onOpenFileRequest.fire(request)); ipc.on('vscode:osResume', () => this._onOsResume.fire()); - if (!isWeb) { - const connection = remoteAgentService.getConnection(); - if (connection && connection.remoteAuthority) { - registerRemoteContributions(); - } + const connection = remoteAgentService.getConnection(); + if (connection && connection.remoteAuthority) { + registerRemoteContributions(); } } From 32da7fe41ecd0b44f48f913e02a890e967416462 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Wed, 19 Jun 2019 19:35:25 +0000 Subject: [PATCH 124/364] fixes #75703 --- src/vs/workbench/browser/actions/layoutActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 9bffa5213e78f..51962ccc1b8f7 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -18,7 +18,7 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation import { KeyMod, KeyCode, KeyChord } from 'vs/base/common/keyCodes'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { MenuBarVisibility } from 'vs/platform/windows/common/windows'; -import { isWindows, isLinux } from 'vs/base/common/platform'; +import { isWindows, isLinux, isWeb } from 'vs/base/common/platform'; import { IsMacNativeContext } from 'vs/workbench/browser/contextkeys'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { InEditorZenModeContext, IsCenteredLayoutContext } from 'vs/workbench/common/editor'; @@ -438,7 +438,7 @@ export class ToggleMenuBarAction extends Action { } } -if (isWindows || isLinux) { +if (isWindows || isLinux || isWeb) { registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMenuBarAction, ToggleMenuBarAction.ID, ToggleMenuBarAction.LABEL), 'View: Toggle Menu Bar', viewCategory); } From 87e16500d265d393a9e0f8ccd5c3ffcd61103f53 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 12:57:26 -0700 Subject: [PATCH 125/364] Call getDefaultShell via ext host on web Part of #75795 --- .../api/browser/mainThreadTerminalService.ts | 17 +++++++++++++-- .../workbench/api/common/extHost.protocol.ts | 1 + .../api/node/extHostTerminalService.ts | 4 ++++ .../tasks/browser/terminalTaskSystem.ts | 21 +------------------ .../contrib/terminal/browser/terminal.ts | 6 +++++- .../browser/terminalInstanceService.ts | 8 +++++-- .../browser/terminalProcessManager.ts | 2 +- .../terminalInstanceService.ts | 10 +++++---- .../terminalLinkHandler.test.ts | 9 ++++---- 9 files changed, 44 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index c37b7c685f0a6..270f8e332fd57 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -9,6 +9,7 @@ import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceS import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { UriComponents, URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; +import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; @extHostNamedCustomer(MainContext.MainThreadTerminalService) export class MainThreadTerminalService implements MainThreadTerminalServiceShape { @@ -22,10 +23,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape constructor( extHostContext: IExtHostContext, - @ITerminalService private readonly _terminalService: ITerminalService + @ITerminalService private readonly _terminalService: ITerminalService, + @ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService); this._remoteAuthority = extHostContext.remoteAuthority; + + // ITerminalService listeners this._toDispose.push(_terminalService.onInstanceCreated((instance) => { // Delay this message so the TerminalInstance constructor has a chance to finish and // return the ID normally to the extension host. The ID that is passed here will be used @@ -44,6 +48,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.push(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed))); this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._onRequestAvailableShells(r))); + // ITerminalInstanceService listeners + if (terminalInstanceService.onRequestDefaultShell) { + this._toDispose.push(terminalInstanceService.onRequestDefaultShell(r => this._onRequestDefaultShell(r))); + } + // Set initial ext host state this._terminalService.terminalInstances.forEach(t => { this._onTerminalOpened(t); @@ -278,6 +287,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } private _onRequestAvailableShells(resolve: (shells: IShellDefinition[]) => void): void { - this._proxy.$requestAvailableShells().then(shells => resolve(shells)); + this._proxy.$requestAvailableShells().then(e => resolve(e)); + } + + private _onRequestDefaultShell(resolve: (defaultShell: string) => void): void { + this._proxy.$requestDefaultShell().then(e => resolve(e)); } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index bcd55cea583b8..f5c00e92830a4 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1129,6 +1129,7 @@ export interface ExtHostTerminalServiceShape { $acceptProcessRequestLatency(id: number): number; $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; $requestAvailableShells(): Promise; + $requestDefaultShell(): Promise; } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 878127edcc590..9bcfd2d149fac 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -579,6 +579,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return detectAvailableShells(); } + public $requestDefaultShell(): Promise { + return Promise.resolve(getDefaultShell(platform.platform)); + } + private _onProcessExit(id: number, exitCode: number): void { // Remove listeners this._terminalProcesses[id].dispose(); diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index a748fc70f712b..6b7d6af46a012 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -763,25 +763,6 @@ export class TerminalTaskSystem implements ITaskSystem { return nls.localize('TerminalTaskSystem.terminalName', 'Task - {0}', needsFolderQualification ? task.getQualifiedLabel() : task.configurationProperties.name); } - private getDefaultShell(platform: Platform.Platform): string { - let defaultShell: string | undefined = undefined; - try { - defaultShell = this.terminalInstanceService.getDefaultShell(platform); - } catch { - // Do nothing - } - if (!defaultShell) { - // Make up a guess for the default shell. - if (platform === Platform.Platform.Windows) { - defaultShell = 'cmd.exe'; - } else { - defaultShell = 'bash'; - } - console.warn('Cannot get the default shell.'); - } - return defaultShell; - } - private async getUserHome(): Promise { const env = await this.remoteAgentService.getEnvironment(); if (env) { @@ -798,7 +779,7 @@ export class TerminalTaskSystem implements ITaskSystem { let originalCommand = task.command.name; if (isShellCommand) { shellLaunchConfig = { name: terminalName, executable: undefined, args: undefined, waitOnExit }; - this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, this.getDefaultShell(platform), this.terminalService.configHelper, platform); + this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this.terminalInstanceService.getDefaultShell(), this.terminalService.configHelper, platform); let shellSpecified: boolean = false; let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; if (shellOptions) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index b7648c67e3c04..806dcee37d6f3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -9,6 +9,7 @@ import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; +import { Event } from 'vs/base/common/event'; export const ITerminalInstanceService = createDecorator('terminalInstanceService'); @@ -20,16 +21,19 @@ export const ITerminalInstanceService = createDecorator void>; + getXtermConstructor(): Promise; getXtermWebLinksConstructor(): Promise; getXtermSearchConstructor(): Promise; createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; - getDefaultShell(p: Platform): string; /** * Merges the default shell path and args into the provided launch configuration */ mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride?: Platform): void; + + getDefaultShell(): Promise; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index dbbb9313e1255..d00843b80d6b7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -9,6 +9,7 @@ import { Terminal as XTermTerminal } from 'xterm'; import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { IProcessEnvironment } from 'vs/base/common/platform'; +import { Emitter, Event } from 'vs/base/common/event'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -17,6 +18,9 @@ let SearchAddon: typeof XTermSearchAddon; export class TerminalInstanceService implements ITerminalInstanceService { public _serviceBrand: any; + private readonly _onRequestDefaultShell = new Emitter<(defaultShell: string) => void>(); + public get onRequestDefaultShell(): Event<(defaultShell: string) => void> { return this._onRequestDefaultShell.event; } + constructor() { } public async getXtermConstructor(): Promise { @@ -48,8 +52,8 @@ export class TerminalInstanceService implements ITerminalInstanceService { throw new Error('Not implemented'); } - public getDefaultShell(): string { - throw new Error('Not implemented'); + public getDefaultShell(): Promise { + return new Promise(r => this._onRequestDefaultShell.fire(r)); } public async getMainProcessParentEnv(): Promise { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 3eca2ccd977b7..9977b97225569 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -163,7 +163,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { private async _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): Promise { if (!shellLaunchConfig.executable) { - this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, this._terminalInstanceService.getDefaultShell(platform.platform), this._configHelper); + this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this._terminalInstanceService.getDefaultShell(), this._configHelper); } const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 357bd5dc73631..6326711f62810 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -62,10 +62,6 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._instantiationService.createInstance(TerminalProcess, shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty); } - public getDefaultShell(p: Platform): string { - return getDefaultShell(p); - } - public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride: Platform = platform): void { const isWorkspaceShellAllowed = configHelper.checkWorkspaceShellPermissions(platformOverride === Platform.Windows ? OperatingSystem.Windows : (platformOverride === Platform.Mac ? OperatingSystem.Macintosh : OperatingSystem.Linux)); mergeDefaultShellPathAndArgs( @@ -79,6 +75,12 @@ export class TerminalInstanceService implements ITerminalInstanceService { ); } + public getDefaultShell(): Promise { + // Don't go via ext host as that would delay terminal start up until after the extension + // host is ready. + return Promise.resolve(getDefaultShell(platform)); + } + public async getMainProcessParentEnv(): Promise { if (this._mainProcessParentEnv) { return this._mainProcessParentEnv; diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index d6abc8d9ccfc4..99d4a6208b769 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { Platform, OperatingSystem } from 'vs/base/common/platform'; +import { OperatingSystem } from 'vs/base/common/platform'; import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; import * as strings from 'vs/base/common/strings'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -30,6 +30,10 @@ class TestXterm { } class MockTerminalInstanceService implements ITerminalInstanceService { + onRequestDefaultShell: any; + getDefaultShell(): Promise { + throw new Error('Method not implemented.'); + } mergeDefaultShellPathAndArgs(): void { throw new Error('Method not implemented.'); } @@ -49,9 +53,6 @@ class MockTerminalInstanceService implements ITerminalInstanceService { createTerminalProcess(): any { throw new Error('Method not implemented.'); } - getDefaultShell(p: Platform): string { - throw new Error('Method not implemented.'); - } getMainProcessParentEnv(): any { throw new Error('Method not implemented.'); } From 3c5977d06ee8b1459aacf8b0c36802598d67a38e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 22:15:34 +0200 Subject: [PATCH 126/364] #75079 Support multi root workspaces --- .../browser/configurationService.ts | 16 +++++++++------- .../environment/browser/environmentService.ts | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 618fb0bc326f6..f0c0dfe003143 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -37,6 +37,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private completeWorkspaceBarrier: Barrier; private readonly configurationCache: IConfigurationCache; private _configuration: Configuration; + private initialized: boolean = false; private defaultConfiguration: DefaultConfigurationModel; private localUserConfiguration: UserConfiguration | null = null; private remoteUserConfiguration: RemoteUserConfiguration | null = null; @@ -73,6 +74,8 @@ export class WorkspaceService extends Disposable implements IConfigurationServic this.completeWorkspaceBarrier = new Barrier(); this.defaultConfiguration = new DefaultConfigurationModel(); this.configurationCache = configurationCache; + this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), this.workspace); + this.cachedFolderConfigs = new ResourceMap(); if (userSettingsResource) { this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, configurationFileService)); this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); @@ -466,11 +469,12 @@ export class WorkspaceService extends Disposable implements IConfigurationServic const currentConfiguration = this._configuration; this._configuration = new Configuration(this.defaultConfiguration, userConfigurationModel, remoteUserConfigurationModel, workspaceConfiguration, folderConfigurationModels, new ConfigurationModel(), new ResourceMap(), this.workspace); - if (currentConfiguration) { + if (this.initialized) { const changedKeys = this._configuration.compare(currentConfiguration); this.triggerConfigurationChange(new ConfigurationChangeEvent().change(changedKeys), ConfigurationTarget.WORKSPACE); } else { this._onDidChangeConfiguration.fire(new AllKeysConfigurationChangeEvent(this._configuration, ConfigurationTarget.WORKSPACE, this.getTargetConfiguration(ConfigurationTarget.WORKSPACE))); + this.initialized = true; } }); } @@ -489,7 +493,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private onDefaultConfigurationChanged(keys: string[]): void { this.defaultConfiguration = new DefaultConfigurationModel(); this.registerConfigurationSchemas(); - if (this.workspace && this._configuration) { + if (this.workspace) { this._configuration.updateDefaultConfiguration(this.defaultConfiguration); if (this.remoteUserConfiguration) { this._configuration.updateRemoteUserConfiguration(this.remoteUserConfiguration.reprocess()); @@ -545,14 +549,12 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private onRemoteUserConfigurationChanged(userConfiguration: ConfigurationModel): void { - if (this._configuration) { - const keys = this._configuration.compareAndUpdateRemoteUserConfiguration(userConfiguration); - this.triggerConfigurationChange(keys, ConfigurationTarget.USER); - } + const keys = this._configuration.compareAndUpdateRemoteUserConfiguration(userConfiguration); + this.triggerConfigurationChange(keys, ConfigurationTarget.USER); } private onWorkspaceConfigurationChanged(): Promise { - if (this.workspace && this.workspace.configuration && this._configuration) { + if (this.workspace && this.workspace.configuration) { const workspaceConfigurationChangeEvent = this._configuration.compareAndUpdateWorkspaceConfiguration(this.workspaceConfiguration.getConfiguration()); let configuredFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), this.workspace.configuration); const changes = this.compareFolders(this.workspace.folders, configuredFolders); diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 8ef1e38761c04..d51cff0cb6f7a 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -13,6 +13,7 @@ import { ExportData } from 'vs/base/common/performance'; import { LogLevel } from 'vs/platform/log/common/log'; import { joinPath } from 'vs/base/common/resources'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; +import { Schemas } from 'vs/base/common/network'; export class BrowserWindowConfiguration implements IWindowConfiguration { @@ -82,6 +83,7 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService { }; this.webviewEndpoint = configuration.webviewEndpoint; + this.untitledWorkspacesHome = URI.from({ scheme: Schemas.untitled, path: 'Workspaces' }); } untitledWorkspacesHome: URI; From 8fb99cd96755183910ed1bfd4d66fba2cb5104cd Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 23:17:13 +0200 Subject: [PATCH 127/364] product service for web - get product configuration from server --- src/vs/code/browser/workbench/workbench.html | 3 + .../product/browser/productService.ts | 37 ++++++++ src/vs/platform/product/common/product.ts | 85 ++++++++++++++++++ src/vs/platform/product/node/product.ts | 86 +------------------ src/vs/workbench/browser/web.main.ts | 5 +- .../workbench/browser/web.simpleservices.ts | 18 ---- .../languageSurveys.contribution.ts | 3 +- .../userData/common/userDataService.ts | 27 ++++++ src/vs/workbench/workbench.web.main.ts | 1 - 9 files changed, 158 insertions(+), 107 deletions(-) create mode 100644 src/vs/platform/product/browser/productService.ts create mode 100644 src/vs/workbench/services/userData/common/userDataService.ts diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index fedadf22ee6da..ff62e0a65a939 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -15,6 +15,9 @@ + + + diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts new file mode 100644 index 0000000000000..084144d009f35 --- /dev/null +++ b/src/vs/platform/product/browser/productService.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; + +export class ProductService implements IProductService { + + private readonly productConfiguration: IProductConfiguration | null; + + constructor() { + const element = document.getElementById('vscode-remote-product-configuration'); + this.productConfiguration = element ? JSON.parse(element.getAttribute('data-settings')!) : null; + } + + _serviceBrand: ServiceIdentifier; + + get version(): string { return '1.35.0'; } + + get commit(): string | undefined { return undefined; } + + get nameLong(): string { return ''; } + + get urlProtocol(): string { return ''; } + + get extensionAllowedProposedApi(): string[] { return this.productConfiguration ? this.productConfiguration.extensionAllowedProposedApi : []; } + + get uiExtensions(): string[] | undefined { return this.productConfiguration ? this.productConfiguration.uiExtensions : undefined; } + + get enableTelemetry(): boolean { return false; } + + get sendASmile(): { reportIssueUrl: string, requestFeatureUrl: string } | undefined { return this.productConfiguration ? this.productConfiguration.sendASmile : undefined; } + + get extensionsGallery() { return this.productConfiguration ? this.productConfiguration.extensionsGallery : undefined; } +} \ No newline at end of file diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index 2a35190f8aebc..97f3fe3e5a41f 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -30,4 +30,89 @@ export interface IProductService { reportIssueUrl: string; requestFeatureUrl: string; }; +} + +export interface IProductConfiguration { + nameShort: string; + nameLong: string; + applicationName: string; + win32AppId: string; + win32x64AppId: string; + win32UserAppId: string; + win32x64UserAppId: string; + win32AppUserModelId: string; + win32MutexName: string; + darwinBundleIdentifier: string; + urlProtocol: string; + dataFolderName: string; + downloadUrl: string; + updateUrl?: string; + quality?: string; + target?: string; + commit?: string; + settingsSearchBuildId?: number; + settingsSearchUrl?: string; + experimentsUrl?: string; + date: string; + extensionsGallery?: { + serviceUrl: string; + itemUrl: string; + controlUrl: string; + recommendationsUrl: string; + }; + extensionTips: { [id: string]: string; }; + extensionImportantTips: { [id: string]: { name: string; pattern: string; }; }; + exeBasedExtensionTips: { [id: string]: { friendlyName: string, windowsPath?: string, recommendations: string[] }; }; + extensionKeywords: { [extension: string]: string[]; }; + extensionAllowedBadgeProviders: string[]; + extensionAllowedProposedApi: string[]; + keymapExtensionTips: string[]; + crashReporter: { + companyName: string; + productName: string; + }; + welcomePage: string; + enableTelemetry: boolean; + aiConfig: { + asimovKey: string; + }; + sendASmile: { + reportIssueUrl: string, + requestFeatureUrl: string + }; + documentationUrl: string; + releaseNotesUrl: string; + keyboardShortcutsUrlMac: string; + keyboardShortcutsUrlLinux: string; + keyboardShortcutsUrlWin: string; + introductoryVideosUrl: string; + tipsAndTricksUrl: string; + newsletterSignupUrl: string; + twitterUrl: string; + requestFeatureUrl: string; + reportIssueUrl: string; + licenseUrl: string; + privacyStatementUrl: string; + telemetryOptOutUrl: string; + npsSurveyUrl: string; + surveys: ISurveyData[]; + checksums: { [path: string]: string; }; + checksumFailMoreInfoUrl: string; + hockeyApp: { + 'win32-ia32': string; + 'win32-x64': string; + 'linux-x64': string; + 'darwin': string; + }; + logUploaderUrl: string; + portable?: string; + uiExtensions?: string[]; +} + +export interface ISurveyData { + surveyId: string; + surveyUrl: string; + languageId: string; + editCount: number; + userProbability: number; } \ No newline at end of file diff --git a/src/vs/platform/product/node/product.ts b/src/vs/platform/product/node/product.ts index 6a5cf7880e8c6..08610d71a1a2b 100644 --- a/src/vs/platform/product/node/product.ts +++ b/src/vs/platform/product/node/product.ts @@ -5,91 +5,7 @@ import * as path from 'vs/base/common/path'; import { getPathFromAmdModule } from 'vs/base/common/amd'; - -export interface IProductConfiguration { - nameShort: string; - nameLong: string; - applicationName: string; - win32AppId: string; - win32x64AppId: string; - win32UserAppId: string; - win32x64UserAppId: string; - win32AppUserModelId: string; - win32MutexName: string; - darwinBundleIdentifier: string; - urlProtocol: string; - dataFolderName: string; - downloadUrl: string; - updateUrl?: string; - quality?: string; - target?: string; - commit?: string; - settingsSearchBuildId?: number; - settingsSearchUrl?: string; - experimentsUrl?: string; - date: string; - extensionsGallery?: { - serviceUrl: string; - itemUrl: string; - controlUrl: string; - recommendationsUrl: string; - }; - extensionTips: { [id: string]: string; }; - extensionImportantTips: { [id: string]: { name: string; pattern: string; }; }; - exeBasedExtensionTips: { [id: string]: { friendlyName: string, windowsPath?: string, recommendations: string[] }; }; - extensionKeywords: { [extension: string]: string[]; }; - extensionAllowedBadgeProviders: string[]; - extensionAllowedProposedApi: string[]; - keymapExtensionTips: string[]; - crashReporter: { - companyName: string; - productName: string; - }; - welcomePage: string; - enableTelemetry: boolean; - aiConfig: { - asimovKey: string; - }; - sendASmile: { - reportIssueUrl: string, - requestFeatureUrl: string - }; - documentationUrl: string; - releaseNotesUrl: string; - keyboardShortcutsUrlMac: string; - keyboardShortcutsUrlLinux: string; - keyboardShortcutsUrlWin: string; - introductoryVideosUrl: string; - tipsAndTricksUrl: string; - newsletterSignupUrl: string; - twitterUrl: string; - requestFeatureUrl: string; - reportIssueUrl: string; - licenseUrl: string; - privacyStatementUrl: string; - telemetryOptOutUrl: string; - npsSurveyUrl: string; - surveys: ISurveyData[]; - checksums: { [path: string]: string; }; - checksumFailMoreInfoUrl: string; - hockeyApp: { - 'win32-ia32': string; - 'win32-x64': string; - 'linux-x64': string; - 'darwin': string; - }; - logUploaderUrl: string; - portable?: string; - uiExtensions?: string[]; -} - -export interface ISurveyData { - surveyId: string; - surveyUrl: string; - languageId: string; - editCount: number; - userProbability: number; -} +import { IProductConfiguration } from 'vs/platform/product/common/product'; const rootPath = path.dirname(getPathFromAmdModule(require, '')); const productJsonPath = path.join(rootPath, 'product.json'); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index d728c10001136..6f1954ba2520a 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -8,7 +8,7 @@ import { domContentLoaded, addDisposableListener, EventType } from 'vs/base/brow import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { ILogService } from 'vs/platform/log/common/log'; import { Disposable } from 'vs/base/common/lifecycle'; -import { SimpleLogService, SimpleProductService } from 'vs/workbench/browser/web.simpleservices'; +import { SimpleLogService } from 'vs/workbench/browser/web.simpleservices'; import { BrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'; import { Workbench } from 'vs/workbench/browser/workbench'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; @@ -35,6 +35,7 @@ import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; +import { ProductService } from 'vs/platform/product/browser/productService'; class CodeRendererMain extends Disposable { @@ -90,7 +91,7 @@ class CodeRendererMain extends Disposable { serviceCollection.set(IWorkbenchEnvironmentService, environmentService); // Product - const productService = new SimpleProductService(); + const productService = new ProductService(); serviceCollection.set(IProductService, productService); // Remote diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 9298d9ce924c4..96d6991045614 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -23,7 +23,6 @@ import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { ITelemetryService, ITelemetryData, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { ConsoleLogService } from 'vs/platform/log/common/log'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { IProductService } from 'vs/platform/product/common/product'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IStorageService, IWorkspaceStorageChangeEvent, StorageScope, IWillSaveStateEvent, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { IUpdateService, State } from 'vs/platform/update/common/update'; @@ -517,23 +516,6 @@ export class SimpleMultiExtensionsManagementService implements IExtensionManagem //#endregion -//#region Product - -export class SimpleProductService implements IProductService { - - _serviceBrand: any; - - version: string = '1.35.0'; - commit?: string; - nameLong: string = ''; - urlProtocol: string = ''; - extensionAllowedProposedApi: string[] = []; - uiExtensions?: string[]; - enableTelemetry: boolean = false; -} - -//#endregion - //#region Request export const IRequestService = createDecorator('requestService'); diff --git a/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts b/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts index 447a356588151..ec9ac3fb2b770 100644 --- a/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts +++ b/src/vs/workbench/contrib/surveys/electron-browser/languageSurveys.contribution.ts @@ -11,7 +11,8 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import pkg from 'vs/platform/product/node/package'; -import product, { ISurveyData } from 'vs/platform/product/node/product'; +import product from 'vs/platform/product/node/product'; +import { ISurveyData } from 'vs/platform/product/common/product'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Severity, INotificationService } from 'vs/platform/notification/common/notification'; import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/common/textfiles'; diff --git a/src/vs/workbench/services/userData/common/userDataService.ts b/src/vs/workbench/services/userData/common/userDataService.ts new file mode 100644 index 0000000000000..64fb82202a3dc --- /dev/null +++ b/src/vs/workbench/services/userData/common/userDataService.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { Event } from 'vs/base/common/event'; + +export const IUserDataService = createDecorator('userDataService'); + +export interface IUserDataService { + _serviceBrand: any; + + onDidChange: Event; + + read(key: string): Promise; + + write(key: string, value: string): Promise; +} + +export const IUserDataEditorService = createDecorator('userDataEditorService'); + +export interface IUserDataEditorService { + _serviceBrand: any; + + openInEditor(key: string): Promise; +} \ No newline at end of file diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 7bdf1ac3687fc..025e107af2a12 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -157,7 +157,6 @@ registerSingleton(IContextViewService, ContextViewService, true); registerSingleton(ILifecycleService, BrowserLifecycleService); // registerSingleton(ILocalizationsService, LocalizationsService); // registerSingleton(ISharedProcessService, SharedProcessService, true); -// registerSingleton(IProductService, ProductService, true); // registerSingleton(IWindowsService, WindowsService); // registerSingleton(IUpdateService, UpdateService); // registerSingleton(IIssueService, IssueService); From 7053a76da2cd7677ab3d33a80d377594cc0592d8 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 19 Jun 2019 23:19:21 +0200 Subject: [PATCH 128/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6916b4088ec60..194d5b8211ed5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "26125d2b5b10bac3b3de09f4ee565ea4d5c1c7bc", + "distro": "3e1131ebd0c20e1929317fcb7925e915007b1303", "author": { "name": "Microsoft Corporation" }, From 24cdcfa52aad0625925abec263712f813d5ab184 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 14:44:39 -0700 Subject: [PATCH 129/364] perpare for bundling --- .../browser/keyboardLayouts/layout.contribution.darwin.ts | 4 +++- .../browser/keyboardLayouts/layout.contribution.linux.ts | 2 ++ .../browser/keyboardLayouts/layout.contribution.win.ts | 2 ++ .../workbench/services/keybinding/browser/keymapService.ts | 5 ++--- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts index 043b9e0261f28..8de0fa205a3ad 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.darwin.ts @@ -17,4 +17,6 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin'; -import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin'; \ No newline at end of file +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin'; + +export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts index b1aeb2eafd5b7..6561501fce42e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.linux.ts @@ -8,3 +8,5 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux'; + +export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts index 5bc8dd0c5303f..bb85b252f901c 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.win.ts @@ -25,3 +25,5 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win'; import 'vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win'; + +export { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index bd005db83b85f..12cae6abfaeff 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -29,7 +29,6 @@ import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationN import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; export class BrowserKeyboardMapperFactory { public static readonly INSTANCE = new BrowserKeyboardMapperFactory(); @@ -77,8 +76,8 @@ export class BrowserKeyboardMapperFactory { const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; - import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then(() => { - this._keymapInfos.push(...KeyboardLayoutContribution.INSTANCE.layoutInfos); + import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then((m) => { + this._keymapInfos.push(...m.KeyboardLayoutContribution.INSTANCE.layoutInfos); this._mru = this._keymapInfos; this._initialized = true; this.onKeyboardLayoutChanged(); From 146eb0714a4f38eadf3129f74bcb6ff0179ec039 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 00:08:27 +0200 Subject: [PATCH 130/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 194d5b8211ed5..daad56f2151e3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "3e1131ebd0c20e1929317fcb7925e915007b1303", + "distro": "2db0078dd120f831be4c40bf03fca6ad584f77d0", "author": { "name": "Microsoft Corporation" }, From 0aab08edf27db421b8a1a764e4f30ca4b8629255 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 15:25:44 -0700 Subject: [PATCH 131/364] Add getDefaultShellAndArgs Also differentiate default from system shell --- .../api/browser/mainThreadTerminalService.ts | 17 ++++------- .../workbench/api/common/extHost.protocol.ts | 6 ++++ .../api/node/extHostTerminalService.ts | 29 +++++++++++++++---- .../workbench/contrib/debug/node/terminals.ts | 8 ++--- .../tasks/browser/terminalTaskSystem.ts | 4 +-- .../contrib/terminal/browser/terminal.ts | 4 ++- .../browser/terminalInstanceService.ts | 8 ++++- .../browser/terminalProcessManager.ts | 4 ++- .../contrib/terminal/common/terminal.ts | 4 +++ .../terminal/common/terminalEnvironment.ts | 3 +- .../electron-browser/terminal.contribution.ts | 4 +-- .../terminalInstanceService.ts | 23 +++++++++++++-- .../contrib/terminal/node/terminal.ts | 15 ++++++---- .../terminalLinkHandler.test.ts | 5 ++++ 14 files changed, 98 insertions(+), 36 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 270f8e332fd57..e730222d096e9 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IShellDefinition } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY } from 'vs/workbench/contrib/terminal/common/terminal'; import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { UriComponents, URI } from 'vs/base/common/uri'; @@ -46,11 +46,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.push(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); this._toDispose.push(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); this._toDispose.push(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed))); - this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._onRequestAvailableShells(r))); + this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._proxy.$requestAvailableShells().then(e => r(e)))); // ITerminalInstanceService listeners if (terminalInstanceService.onRequestDefaultShell) { - this._toDispose.push(terminalInstanceService.onRequestDefaultShell(r => this._onRequestDefaultShell(r))); + this._toDispose.push(terminalInstanceService.onRequestDefaultShell(r => this._proxy.$requestDefaultShell().then(e => r(e)))); + } + if (terminalInstanceService.onRequestDefaultShellAndArgs) { + this._toDispose.push(terminalInstanceService.onRequestDefaultShellAndArgs(r => this._proxy.$requestDefaultShellAndArgs().then(e => r(e.shell, e.args)))); } // Set initial ext host state @@ -285,12 +288,4 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape } this._terminalProcesses[terminalId].emitLatency(sum / COUNT); } - - private _onRequestAvailableShells(resolve: (shells: IShellDefinition[]) => void): void { - this._proxy.$requestAvailableShells().then(e => resolve(e)); - } - - private _onRequestDefaultShell(resolve: (defaultShell: string) => void): void { - this._proxy.$requestDefaultShell().then(e => resolve(e)); - } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index f5c00e92830a4..e3ceb14440ade 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1111,6 +1111,11 @@ export interface IShellDefinitionDto { path: string; } +export interface IShellAndArgsDto { + shell: string; + args: string[] | string | undefined; +} + export interface ExtHostTerminalServiceShape { $acceptTerminalClosed(id: number): void; $acceptTerminalOpened(id: number, name: string): void; @@ -1130,6 +1135,7 @@ export interface ExtHostTerminalServiceShape { $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; $requestAvailableShells(): Promise; $requestDefaultShell(): Promise; + $requestDefaultShellAndArgs(): Promise; } export interface ExtHostSCMShape { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 9bcfd2d149fac..749487c88e19f 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -10,7 +10,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Event, Emitter } from 'vs/base/common/event'; -import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -20,7 +20,7 @@ import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ExtHostVariableResolverService } from 'vs/workbench/api/node/extHostDebugService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors'; -import { getDefaultShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getSystemShell, detectAvailableShells } from 'vs/workbench/contrib/terminal/node/terminal'; const RENDERER_NO_PROCESS_ID = -1; @@ -338,12 +338,22 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return terminalEnvironment.getDefaultShell( fetchSetting, this._isWorkspaceShellAllowed, - getDefaultShell(platform.platform), + getSystemShell(platform.platform), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir ); } + private _getDefaultShellArgs(configProvider: ExtHostConfigProvider): string[] | string | undefined { + const fetchSetting = (key: string) => { + const setting = configProvider + .getConfiguration(key.substr(0, key.lastIndexOf('.'))) + .inspect(key.substr(key.lastIndexOf('.') + 1)); + return this._apiInspectConfigToPlain(setting); + }; + return terminalEnvironment.getDefaultShellArgs(fetchSetting, this._isWorkspaceShellAllowed); + } + public async resolveTerminalRenderer(id: number): Promise { // Check to see if the extension host already knows about this terminal. for (const terminalRenderer of this._terminalRenderers) { @@ -495,7 +505,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { shellLaunchConfig, fetchSetting, isWorkspaceShellAllowed || false, - getDefaultShell(platform.platform), + getSystemShell(platform.platform), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), process.env.windir ); @@ -579,8 +589,17 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return detectAvailableShells(); } + // TODO: Remove this once requestDefaultShellAndArgs is working public $requestDefaultShell(): Promise { - return Promise.resolve(getDefaultShell(platform.platform)); + return Promise.resolve(getSystemShell(platform.platform)); + } + + public async $requestDefaultShellAndArgs(): Promise { + const configProvider = await this._extHostConfiguration.getConfigProvider(); + return Promise.resolve({ + shell: this.getDefaultShell(configProvider), + args: this._getDefaultShellArgs(configProvider) + }); } private _onProcessExit(id: number, exitCode: number): void { diff --git a/src/vs/workbench/contrib/debug/node/terminals.ts b/src/vs/workbench/contrib/debug/node/terminals.ts index 300c738f0eb4a..164dd27a15a5d 100644 --- a/src/vs/workbench/contrib/debug/node/terminals.ts +++ b/src/vs/workbench/contrib/debug/node/terminals.ts @@ -10,7 +10,7 @@ import * as pfs from 'vs/base/node/pfs'; import { assign } from 'vs/base/common/objects'; import { ITerminalLauncher, ITerminalSettings } from 'vs/workbench/contrib/debug/common/debug'; import { getPathFromAmdModule } from 'vs/base/common/amd'; -import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal'; const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console"); @@ -315,13 +315,13 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments let shell: string; const shell_config = config.integrated.shell; if (env.isWindows) { - shell = shell_config.windows || getDefaultShell(env.Platform.Windows); + shell = shell_config.windows || getSystemShell(env.Platform.Windows); shellType = ShellType.cmd; } else if (env.isLinux) { - shell = shell_config.linux || getDefaultShell(env.Platform.Linux); + shell = shell_config.linux || getSystemShell(env.Platform.Linux); shellType = ShellType.bash; } else if (env.isMacintosh) { - shell = shell_config.osx || getDefaultShell(env.Platform.Mac); + shell = shell_config.osx || getSystemShell(env.Platform.Mac); shellType = ShellType.bash; } else { throw new Error('Unknown platform'); diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 6b7d6af46a012..a481fcc0f6965 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -778,8 +778,8 @@ export class TerminalTaskSystem implements ITaskSystem { let terminalName = this.createTerminalName(task); let originalCommand = task.command.name; if (isShellCommand) { - shellLaunchConfig = { name: terminalName, executable: undefined, args: undefined, waitOnExit }; - this.terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this.terminalInstanceService.getDefaultShell(), this.terminalService.configHelper, platform); + const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(); + shellLaunchConfig = { name: terminalName, executable: defaultConfig.shell, args: defaultConfig.args, waitOnExit }; let shellSpecified: boolean = false; let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; if (shellOptions) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 806dcee37d6f3..bdc6f1e61710f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -6,7 +6,7 @@ import { Terminal as XTermTerminal } from 'xterm'; import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; -import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; @@ -22,6 +22,7 @@ export interface ITerminalInstanceService { _serviceBrand: any; onRequestDefaultShell?: Event<(defaultShell: string) => void>; + onRequestDefaultShellAndArgs?: Event; getXtermConstructor(): Promise; getXtermWebLinksConstructor(): Promise; @@ -34,6 +35,7 @@ export interface ITerminalInstanceService { mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride?: Platform): void; getDefaultShell(): Promise; + getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index d00843b80d6b7..1b708b0e2e501 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { IWindowsShellHelper, ITerminalChildProcess } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IWindowsShellHelper, ITerminalChildProcess, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal'; import { Terminal as XTermTerminal } from 'xterm'; import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; @@ -20,6 +20,8 @@ export class TerminalInstanceService implements ITerminalInstanceService { private readonly _onRequestDefaultShell = new Emitter<(defaultShell: string) => void>(); public get onRequestDefaultShell(): Event<(defaultShell: string) => void> { return this._onRequestDefaultShell.event; } + private readonly _onRequestDefaultShellAndArgs = new Emitter(); + public get onRequestDefaultShellAndArgs(): Event { return this._onRequestDefaultShellAndArgs.event; } constructor() { } @@ -56,6 +58,10 @@ export class TerminalInstanceService implements ITerminalInstanceService { return new Promise(r => this._onRequestDefaultShell.fire(r)); } + public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { + return new Promise(r => this._onRequestDefaultShellAndArgs.fire((shell, args) => r({ shell, args }))); + } + public async getMainProcessParentEnv(): Promise { return {}; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 9977b97225569..723cbe41cd42f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -163,7 +163,9 @@ export class TerminalProcessManager implements ITerminalProcessManager { private async _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): Promise { if (!shellLaunchConfig.executable) { - this._terminalInstanceService.mergeDefaultShellPathAndArgs(shellLaunchConfig, await this._terminalInstanceService.getDefaultShell(), this._configHelper); + const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(); + shellLaunchConfig.executable = defaultConfig.shell; + shellLaunchConfig.args = defaultConfig.args; } const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(Schemas.file); diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 7c7d7824119f8..2c49b9dff8e74 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -789,4 +789,8 @@ export interface ITerminalChildProcess { getInitialCwd(): Promise; getCwd(): Promise; getLatency(): Promise; +} + +export interface IDefaultShellAndArgsRequest { + (shell: string, args: string[] | string | undefined): void; } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 78a6f0e734f81..0ff17ebf44027 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -192,7 +192,7 @@ export function getDefaultShell( return executable; } -function getDefaultShellArgs( +export function getDefaultShellArgs( fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, isWorkspaceShellAllowed: boolean, platformOverride: platform.Platform = platform.platform @@ -203,6 +203,7 @@ function getDefaultShellArgs( return args; } +// TODO: Remove this? export function mergeDefaultShellPathAndArgs( shell: IShellLaunchConfig, fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts index 9937eea4c5bbc..f9dd46267cac4 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminal.contribution.ts @@ -6,11 +6,11 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalInstanceService } from 'vs/workbench/contrib/terminal/electron-browser/terminalInstanceService'; -import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal'; import { registerShellConfiguration } from 'vs/workbench/contrib/terminal/common/terminalShellConfig'; import { TerminalNativeService } from 'vs/workbench/contrib/terminal/electron-browser/terminalNativeService'; import { ITerminalNativeService } from 'vs/workbench/contrib/terminal/common/terminal'; -registerShellConfiguration(getDefaultShell); +registerShellConfiguration(getSystemShell); registerSingleton(ITerminalNativeService, TerminalNativeService, true); registerSingleton(ITerminalInstanceService, TerminalInstanceService, true); diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 6326711f62810..cc8d96b81d5c6 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -9,14 +9,14 @@ import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsSh import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment, Platform, isLinux, isMacintosh, isWindows, OperatingSystem, platform } from 'vs/base/common/platform'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; -import { getDefaultShell } from 'vs/workbench/contrib/terminal/node/terminal'; +import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal'; import { Terminal as XTermTerminal } from 'xterm'; import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { readFile } from 'vs/base/node/pfs'; import { basename } from 'vs/base/common/path'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { mergeDefaultShellPathAndArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { mergeDefaultShellPathAndArgs, getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -78,7 +78,24 @@ export class TerminalInstanceService implements ITerminalInstanceService { public getDefaultShell(): Promise { // Don't go via ext host as that would delay terminal start up until after the extension // host is ready. - return Promise.resolve(getDefaultShell(platform)); + return Promise.resolve(getSystemShell(platform)); + } + + public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { + // TODO: Pull the workspace shell permissions setting + const isWorkspaceShellAllowed = false; // configHelper.checkWorkspaceShellPermissions(platform); + const shell = getDefaultShell( + (key) => this._configurationService.inspect(key), + isWorkspaceShellAllowed, + getSystemShell(platform), + process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), + process.env.windir + ); + const args = getDefaultShellArgs( + (key) => this._configurationService.inspect(key), + isWorkspaceShellAllowed + ); + return Promise.resolve({ shell, args }); } public async getMainProcessParentEnv(): Promise { diff --git a/src/vs/workbench/contrib/terminal/node/terminal.ts b/src/vs/workbench/contrib/terminal/node/terminal.ts index 195879eb52f80..00cd0d8a33aa3 100644 --- a/src/vs/workbench/contrib/terminal/node/terminal.ts +++ b/src/vs/workbench/contrib/terminal/node/terminal.ts @@ -11,10 +11,15 @@ import { LinuxDistro, IShellDefinition } from 'vs/workbench/contrib/terminal/com import { coalesce } from 'vs/base/common/arrays'; import { normalize, basename } from 'vs/base/common/path'; -export function getDefaultShell(p: platform.Platform): string { +/** + * Gets the detected default shell for the _system_, not to be confused with VS Code's _default_ + * shell that the terminal uses by default. + * @param p The platform to detect the shell of. + */ +export function getSystemShell(p: platform.Platform): string { if (p === platform.Platform.Windows) { if (platform.isWindows) { - return getTerminalDefaultShellWindows(); + return getSystemShellWindows(); } // Don't detect Windows shell when not on Windows return processes.getWindowsShell(); @@ -23,11 +28,11 @@ export function getDefaultShell(p: platform.Platform): string { if (platform.isLinux && p === platform.Platform.Mac || platform.isMacintosh && p === platform.Platform.Linux) { return '/bin/bash'; } - return getTerminalDefaultShellUnixLike(); + return getSystemShellUnixLike(); } let _TERMINAL_DEFAULT_SHELL_UNIX_LIKE: string | null = null; -function getTerminalDefaultShellUnixLike(): string { +function getSystemShellUnixLike(): string { if (!_TERMINAL_DEFAULT_SHELL_UNIX_LIKE) { let unixLikeTerminal = 'sh'; if (!platform.isWindows && process.env.SHELL) { @@ -46,7 +51,7 @@ function getTerminalDefaultShellUnixLike(): string { } let _TERMINAL_DEFAULT_SHELL_WINDOWS: string | null = null; -function getTerminalDefaultShellWindows(): string { +function getSystemShellWindows(): string { if (!_TERMINAL_DEFAULT_SHELL_WINDOWS) { const isAtLeastWindows10 = platform.isWindows && parseFloat(os.release()) >= 10; const is32ProcessOn64Windows = process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'); diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index 99d4a6208b769..1e5162d8f70ee 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -8,6 +8,7 @@ import { OperatingSystem } from 'vs/base/common/platform'; import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/contrib/terminal/browser/terminalLinkHandler'; import * as strings from 'vs/base/common/strings'; import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { Event } from 'vs/base/common/event'; class TestTerminalLinkHandler extends TerminalLinkHandler { public get localLinkRegex(): RegExp { @@ -30,6 +31,10 @@ class TestXterm { } class MockTerminalInstanceService implements ITerminalInstanceService { + onRequestDefaultShellAndArgs?: Event | undefined; + getDefaultShellAndArgs(): Promise<{ shell: string; args: string | string[] | undefined; }> { + throw new Error('Method not implemented.'); + } onRequestDefaultShell: any; getDefaultShell(): Promise { throw new Error('Method not implemented.'); From 994bfe2d6a7df0cc60867dd9acbd812636469f4b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 15:31:44 -0700 Subject: [PATCH 132/364] Remove getDefaultShell --- .../api/browser/mainThreadTerminalService.ts | 3 --- src/vs/workbench/api/common/extHost.protocol.ts | 1 - .../workbench/api/node/extHostTerminalService.ts | 5 ----- .../workbench/contrib/terminal/browser/terminal.ts | 2 -- .../terminal/browser/terminalInstanceService.ts | 6 ------ .../contrib/terminal/common/terminalShellConfig.ts | 14 +++++++------- .../electron-browser/terminalInstanceService.ts | 6 ------ .../electron-browser/terminalLinkHandler.test.ts | 4 ---- 8 files changed, 7 insertions(+), 34 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index e730222d096e9..ff3183d07128d 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -49,9 +49,6 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.push(_terminalService.onRequestAvailableShells(r => this._proxy.$requestAvailableShells().then(e => r(e)))); // ITerminalInstanceService listeners - if (terminalInstanceService.onRequestDefaultShell) { - this._toDispose.push(terminalInstanceService.onRequestDefaultShell(r => this._proxy.$requestDefaultShell().then(e => r(e)))); - } if (terminalInstanceService.onRequestDefaultShellAndArgs) { this._toDispose.push(terminalInstanceService.onRequestDefaultShellAndArgs(r => this._proxy.$requestDefaultShellAndArgs().then(e => r(e.shell, e.args)))); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index e3ceb14440ade..9d7bb48a9cad1 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1134,7 +1134,6 @@ export interface ExtHostTerminalServiceShape { $acceptProcessRequestLatency(id: number): number; $acceptWorkspacePermissionsChanged(isAllowed: boolean): void; $requestAvailableShells(): Promise; - $requestDefaultShell(): Promise; $requestDefaultShellAndArgs(): Promise; } diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 749487c88e19f..5a2aff7018d0f 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -589,11 +589,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { return detectAvailableShells(); } - // TODO: Remove this once requestDefaultShellAndArgs is working - public $requestDefaultShell(): Promise { - return Promise.resolve(getSystemShell(platform.platform)); - } - public async $requestDefaultShellAndArgs(): Promise { const configProvider = await this._extHostConfiguration.getConfigProvider(); return Promise.resolve({ diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index bdc6f1e61710f..36b30c70160e6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -21,7 +21,6 @@ export const ITerminalInstanceService = createDecorator void>; onRequestDefaultShellAndArgs?: Event; getXtermConstructor(): Promise; @@ -34,7 +33,6 @@ export interface ITerminalInstanceService { */ mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride?: Platform): void; - getDefaultShell(): Promise; getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index 1b708b0e2e501..099aaf41c5ea5 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -18,8 +18,6 @@ let SearchAddon: typeof XTermSearchAddon; export class TerminalInstanceService implements ITerminalInstanceService { public _serviceBrand: any; - private readonly _onRequestDefaultShell = new Emitter<(defaultShell: string) => void>(); - public get onRequestDefaultShell(): Event<(defaultShell: string) => void> { return this._onRequestDefaultShell.event; } private readonly _onRequestDefaultShellAndArgs = new Emitter(); public get onRequestDefaultShellAndArgs(): Event { return this._onRequestDefaultShellAndArgs.event; } @@ -54,10 +52,6 @@ export class TerminalInstanceService implements ITerminalInstanceService { throw new Error('Not implemented'); } - public getDefaultShell(): Promise { - return new Promise(r => this._onRequestDefaultShell.fire(r)); - } - public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { return new Promise(r => this._onRequestDefaultShellAndArgs.fire((shell, args) => r({ shell, args }))); } diff --git a/src/vs/workbench/contrib/terminal/common/terminalShellConfig.ts b/src/vs/workbench/contrib/terminal/common/terminalShellConfig.ts index 6867fd0187106..c08a6f47fe876 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalShellConfig.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalShellConfig.ts @@ -8,7 +8,7 @@ import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/co import { Registry } from 'vs/platform/registry/common/platform'; import { Platform } from 'vs/base/common/platform'; -export function registerShellConfiguration(getDefaultShell?: (p: Platform) => string): void { +export function registerShellConfiguration(getSystemShell?: (p: Platform) => string): void { const configurationRegistry = Registry.as(Extensions.Configuration); configurationRegistry.registerConfiguration({ id: 'terminal', @@ -18,24 +18,24 @@ export function registerShellConfiguration(getDefaultShell?: (p: Platform) => st properties: { 'terminal.integrated.shell.linux': { markdownDescription: - getDefaultShell - ? nls.localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getDefaultShell(Platform.Linux)) + getSystemShell + ? nls.localize('terminal.integrated.shell.linux', "The path of the shell that the terminal uses on Linux (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getSystemShell(Platform.Linux)) : nls.localize('terminal.integrated.shell.linux.noDefault', "The path of the shell that the terminal uses on Linux. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: ['string', 'null'], default: null }, 'terminal.integrated.shell.osx': { markdownDescription: - getDefaultShell - ? nls.localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on macOS (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getDefaultShell(Platform.Mac)) + getSystemShell + ? nls.localize('terminal.integrated.shell.osx', "The path of the shell that the terminal uses on macOS (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getSystemShell(Platform.Mac)) : nls.localize('terminal.integrated.shell.osx.noDefault', "The path of the shell that the terminal uses on macOS. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: ['string', 'null'], default: null }, 'terminal.integrated.shell.windows': { markdownDescription: - getDefaultShell - ? nls.localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getDefaultShell(Platform.Windows)) + getSystemShell + ? nls.localize('terminal.integrated.shell.windows', "The path of the shell that the terminal uses on Windows (default: {0}). [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration).", getSystemShell(Platform.Windows)) : nls.localize('terminal.integrated.shell.windows.noDefault', "The path of the shell that the terminal uses on Windows. [Read more about configuring the shell](https://code.visualstudio.com/docs/editor/integrated-terminal#_configuration)."), type: ['string', 'null'], default: null diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index cc8d96b81d5c6..912580984b0fa 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -75,12 +75,6 @@ export class TerminalInstanceService implements ITerminalInstanceService { ); } - public getDefaultShell(): Promise { - // Don't go via ext host as that would delay terminal start up until after the extension - // host is ready. - return Promise.resolve(getSystemShell(platform)); - } - public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { // TODO: Pull the workspace shell permissions setting const isWorkspaceShellAllowed = false; // configHelper.checkWorkspaceShellPermissions(platform); diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index 1e5162d8f70ee..e5b3f5d7f3c9d 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -35,10 +35,6 @@ class MockTerminalInstanceService implements ITerminalInstanceService { getDefaultShellAndArgs(): Promise<{ shell: string; args: string | string[] | undefined; }> { throw new Error('Method not implemented.'); } - onRequestDefaultShell: any; - getDefaultShell(): Promise { - throw new Error('Method not implemented.'); - } mergeDefaultShellPathAndArgs(): void { throw new Error('Method not implemented.'); } From 12afb8de03afa885d1b2ce29eceacfdbf850858a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 15:37:52 -0700 Subject: [PATCH 133/364] Get workspace shell permissions correctly --- .../electron-browser/terminalInstanceService.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 912580984b0fa..cfa3ec68b4d03 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, ITerminalConfigHelper, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IProcessEnvironment, Platform, isLinux, isMacintosh, isWindows, OperatingSystem, platform } from 'vs/base/common/platform'; @@ -17,6 +17,7 @@ import { readFile } from 'vs/base/node/pfs'; import { basename } from 'vs/base/common/path'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { mergeDefaultShellPathAndArgs, getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; let Terminal: typeof XTermTerminal; let WebLinksAddon: typeof XTermWebLinksAddon; @@ -29,7 +30,8 @@ export class TerminalInstanceService implements ITerminalInstanceService { constructor( @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IConfigurationService private readonly _configurationService: IConfigurationService + @IConfigurationService private readonly _configurationService: IConfigurationService, + @IStorageService private readonly _storageService: IStorageService ) { } @@ -62,6 +64,10 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._instantiationService.createInstance(TerminalProcess, shellLaunchConfig, cwd, cols, rows, env, windowsEnableConpty); } + private _isWorkspaceShellAllowed(): boolean { + return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); + } + public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride: Platform = platform): void { const isWorkspaceShellAllowed = configHelper.checkWorkspaceShellPermissions(platformOverride === Platform.Windows ? OperatingSystem.Windows : (platformOverride === Platform.Mac ? OperatingSystem.Macintosh : OperatingSystem.Linux)); mergeDefaultShellPathAndArgs( @@ -76,8 +82,7 @@ export class TerminalInstanceService implements ITerminalInstanceService { } public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { - // TODO: Pull the workspace shell permissions setting - const isWorkspaceShellAllowed = false; // configHelper.checkWorkspaceShellPermissions(platform); + const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const shell = getDefaultShell( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, From 7c127de60cb45884d5e925548360cbed84e97fff Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 15:42:15 -0700 Subject: [PATCH 134/364] Remove mergeDefaultShellAndArgs --- .../api/node/extHostTerminalService.ts | 16 ++-------------- .../contrib/terminal/browser/terminal.ts | 6 +----- .../browser/terminalInstanceService.ts | 3 --- .../terminal/common/terminalEnvironment.ts | 14 -------------- .../terminalInstanceService.ts | 19 +++---------------- .../terminalLinkHandler.test.ts | 3 --- 6 files changed, 6 insertions(+), 55 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 5a2aff7018d0f..e935ccdf20d4b 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -495,20 +495,8 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { const platformKey = platform.isWindows ? 'windows' : (platform.isMacintosh ? 'osx' : 'linux'); const configProvider = await this._extHostConfiguration.getConfigProvider(); if (!shellLaunchConfig.executable) { - const fetchSetting = (key: string) => { - const setting = configProvider - .getConfiguration(key.substr(0, key.lastIndexOf('.'))) - .inspect(key.substr(key.lastIndexOf('.') + 1)); - return this._apiInspectConfigToPlain(setting); - }; - terminalEnvironment.mergeDefaultShellPathAndArgs( - shellLaunchConfig, - fetchSetting, - isWorkspaceShellAllowed || false, - getSystemShell(platform.platform), - process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), - process.env.windir - ); + shellLaunchConfig.executable = this.getDefaultShell(configProvider); + shellLaunchConfig.args = this._getDefaultShellArgs(configProvider); } // Get the initial cwd diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 36b30c70160e6..e67c5dba9247f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -8,7 +8,7 @@ import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; +import { IProcessEnvironment } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; export const ITerminalInstanceService = createDecorator('terminalInstanceService'); @@ -28,10 +28,6 @@ export interface ITerminalInstanceService { getXtermSearchConstructor(): Promise; createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; - /** - * Merges the default shell path and args into the provided launch configuration - */ - mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride?: Platform): void; getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts index 099aaf41c5ea5..08980a9400039 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstanceService.ts @@ -59,7 +59,4 @@ export class TerminalInstanceService implements ITerminalInstanceService { public async getMainProcessParentEnv(): Promise { return {}; } - - public mergeDefaultShellPathAndArgs(): void { - } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 0ff17ebf44027..7309615c7fd37 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -203,20 +203,6 @@ export function getDefaultShellArgs( return args; } -// TODO: Remove this? -export function mergeDefaultShellPathAndArgs( - shell: IShellLaunchConfig, - fetchSetting: (key: string) => { user: string | string[] | undefined, value: string | string[] | undefined, default: string | string[] | undefined }, - isWorkspaceShellAllowed: boolean, - defaultShell: string, - isWoW64: boolean, - windir: string | undefined, - platformOverride: platform.Platform = platform.platform -): void { - shell.executable = getDefaultShell(fetchSetting, isWorkspaceShellAllowed, defaultShell, isWoW64, windir, platformOverride); - shell.args = getDefaultShellArgs(fetchSetting, isWorkspaceShellAllowed, platformOverride); -} - export function createTerminalEnvironment( shellLaunchConfig: IShellLaunchConfig, lastActiveWorkspace: IWorkspaceFolder | null, diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index cfa3ec68b4d03..7b3a08d19780a 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -4,10 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, ITerminalConfigHelper, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IProcessEnvironment, Platform, isLinux, isMacintosh, isWindows, OperatingSystem, platform } from 'vs/base/common/platform'; +import { IProcessEnvironment, isLinux, isMacintosh, isWindows, platform } from 'vs/base/common/platform'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal'; import { Terminal as XTermTerminal } from 'xterm'; @@ -16,7 +16,7 @@ import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { readFile } from 'vs/base/node/pfs'; import { basename } from 'vs/base/common/path'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { mergeDefaultShellPathAndArgs, getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; +import { getDefaultShell, getDefaultShellArgs } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage'; let Terminal: typeof XTermTerminal; @@ -68,19 +68,6 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); } - public mergeDefaultShellPathAndArgs(shell: IShellLaunchConfig, defaultShell: string, configHelper: ITerminalConfigHelper, platformOverride: Platform = platform): void { - const isWorkspaceShellAllowed = configHelper.checkWorkspaceShellPermissions(platformOverride === Platform.Windows ? OperatingSystem.Windows : (platformOverride === Platform.Mac ? OperatingSystem.Macintosh : OperatingSystem.Linux)); - mergeDefaultShellPathAndArgs( - shell, - (key) => this._configurationService.inspect(key), - isWorkspaceShellAllowed, - defaultShell, - process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), - process.env.windir, - platformOverride - ); - } - public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const shell = getDefaultShell( diff --git a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts index e5b3f5d7f3c9d..96daea4ad443a 100644 --- a/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts +++ b/src/vs/workbench/contrib/terminal/test/electron-browser/terminalLinkHandler.test.ts @@ -35,9 +35,6 @@ class MockTerminalInstanceService implements ITerminalInstanceService { getDefaultShellAndArgs(): Promise<{ shell: string; args: string | string[] | undefined; }> { throw new Error('Method not implemented.'); } - mergeDefaultShellPathAndArgs(): void { - throw new Error('Method not implemented.'); - } _serviceBrand: any; getXtermConstructor(): Promise { throw new Error('Method not implemented.'); From a405e419d3f0469fc94fdaffb8dfc33038375e4c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 16:26:26 -0700 Subject: [PATCH 135/364] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index daad56f2151e3..770f731ec1b73 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "2db0078dd120f831be4c40bf03fca6ad584f77d0", + "distro": "555abb7db38aa08e0f905213c013f7bad0747ed2", "author": { "name": "Microsoft Corporation" }, From 850cd65951b1d6e550b0ec374df0603c8dfa4b66 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 17:00:00 -0700 Subject: [PATCH 136/364] beautify macos keyboard layout label --- .../browser/keyboardLayoutPicker.ts | 16 ++++---- .../keybinding/common/keymapService.ts | 41 +++++++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index b05c5974a984a..92c47b46e75cc 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, areKeyboardLayoutsEqual } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService, areKeyboardLayoutsEqual, parseKeyboardLayout } from 'vs/workbench/services/keybinding/common/keymapService'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; @@ -34,10 +34,10 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor let layout = this.keymapService.getCurrentKeyboardLayout(); if (layout) { - let layoutInfo = (layout).text || (layout).lang || (layout).model; + let layoutInfo = parseKeyboardLayout(layout); this.pickerElement.value = this.statusbarService.addEntry( { - text: `Layout: ${layoutInfo}`, + text: `Layout: ${layoutInfo.label}`, // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), command: KEYBOARD_LAYOUT_OPEN_PICKER }, @@ -49,11 +49,11 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor this._register(keymapService.onDidChangeKeyboardMapper(() => { let layout = this.keymapService.getCurrentKeyboardLayout(); - let layoutInfo = (layout).text || (layout).lang || (layout).model; + let layoutInfo = parseKeyboardLayout(layout); if (this.pickerElement.value) { this.pickerElement.value.update({ - text: `Layout: ${layoutInfo}`, + text: `Layout: ${layoutInfo.label}`, command: KEYBOARD_LAYOUT_OPEN_PICKER }); } else { @@ -111,9 +111,11 @@ export class KeyboardLayoutPickerAction extends Action { const picks: QuickPickInput[] = layouts.map(layout => { const picked = !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout); + const layoutInfo = parseKeyboardLayout(layout); return { - label: (layout).text || (layout).lang || (layout).layout, - description: ((layout).id || '') + (picked ? ' (Current selection)' : ''), + label: layoutInfo.label, + id: (layout).text || (layout).lang || (layout).layout, + description: layoutInfo.description + (picked ? ' (Current selection)' : ''), picked: !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout) }; }); diff --git a/src/vs/workbench/services/keybinding/common/keymapService.ts b/src/vs/workbench/services/keybinding/common/keymapService.ts index 19a73c5b7d654..f70f8f20bc827 100644 --- a/src/vs/workbench/services/keybinding/common/keymapService.ts +++ b/src/vs/workbench/services/keybinding/common/keymapService.ts @@ -122,3 +122,44 @@ export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeybo return false; } + +export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { + + + if ((layout).name) { + // windows + let windowsLayout = layout; + return { + label: windowsLayout.text, + description: '' + }; + } + + if ((layout).id) { + let macLayout = layout; + if (/^com\.apple\.keylayout\./.test(macLayout.id)) { + return { + label: macLayout.id.replace(/^com\.apple\.keylayout\./, '').replace(/-/, ' '), + description: '' + }; + } + if (/^.*inputmethod\./.test(macLayout.id)) { + return { + label: macLayout.id.replace(/^.*inputmethod\./, '').replace(/[-\.]/, ' '), + description: `Input Method (${macLayout.lang})` + }; + } + + return { + label: macLayout.lang, + description: '' + }; + } + + let linuxLayout = layout; + + return { + label: linuxLayout.layout, + description: '' + }; +} \ No newline at end of file From 03a5298536ed8046aeafda78104641735e67f585 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 17:01:00 -0700 Subject: [PATCH 137/364] Open folders and workspaces in new windows --- .../workbench/browser/web.simpleservices.ts | 9 ++++ .../files/browser/fileActions.contribution.ts | 51 ++++++++++++++++++- .../electron-browser/main.contribution.ts | 41 +-------------- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 96d6991045614..055c006de7a69 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -850,6 +850,15 @@ export class SimpleWindowService implements IWindowService { } openWindow(_uris: IURIToOpen[], _options?: IOpenSettings): Promise { + // TODO: SUpport window.openFoldersInNewWindow setting + _uris.forEach(uri => { + if ('folderUri' in uri) { + window.open(`${document.location.origin}/?folder=${uri.folderUri.path}`); + } + if ('workspaceUri' in uri) { + window.open(`${document.location.origin}/?folder=${uri.workspaceUri.path}`); + } + }); return Promise.resolve(); } diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 1f20e01c590c1..363a0c6233e25 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -14,7 +14,7 @@ import { openWindowCommand, REVEAL_IN_OS_COMMAND_ID, COPY_PATH_COMMAND_ID, REVEA import { CommandsRegistry, ICommandHandler } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { isWindows, isMacintosh } from 'vs/base/common/platform'; +import { isWindows, isMacintosh, isWeb } from 'vs/base/common/platform'; import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceNotReadonlyContext, ExplorerResourceCut, IExplorerService, ExplorerResourceMoveableToTrash } from 'vs/workbench/contrib/files/common/files'; import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from 'vs/workbench/browser/actions/workspaceCommands'; import { CLOSE_SAVED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; @@ -23,8 +23,9 @@ import { ResourceContextKey } from 'vs/workbench/common/resources'; import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; -import { SupportsWorkspacesContext, IsWebContext } from 'vs/workbench/browser/contextkeys'; +import { SupportsWorkspacesContext, IsWebContext, RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { OpenFileFolderAction, OpenLocalFileFolderAction, OpenFileAction, OpenFolderAction, OpenLocalFileAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; // Contribute Global Actions const category = { value: nls.localize('filesCategory', "File"), original: 'File' }; @@ -41,6 +42,23 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ShowOpenedFileInNewWin registry.registerWorkbenchAction(new SyncActionDescriptor(CompareWithClipboardAction, CompareWithClipboardAction.ID, CompareWithClipboardAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_C) }), 'File: Compare Active File with Clipboard', category.value); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleAutoSaveAction, ToggleAutoSaveAction.ID, ToggleAutoSaveAction.LABEL), 'File: Toggle Auto Save', category.value); + +const fileCategory = nls.localize('file', "File"); + +if (isMacintosh) { + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileFolderAction, OpenFileFolderAction.ID, OpenFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open...', fileCategory); + if (!isWeb) { + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileFolderAction, OpenLocalFileFolderAction.ID, OpenLocalFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local...', fileCategory); + } +} else { + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open File...', fileCategory); + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'File: Open Folder...', fileCategory); + if (!isWeb) { + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileAction, OpenLocalFileAction.ID, OpenLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local File...', fileCategory); + registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFolderAction, OpenLocalFolderAction.ID, OpenLocalFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }, RemoteFileDialogContext), 'File: Open Local Folder...', fileCategory); + } +} + // Commands CommandsRegistry.registerCommand('_files.windowOpen', openWindowCommand); CommandsRegistry.registerCommand('_files.newWindow', newWindowCommand); @@ -586,6 +604,35 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { order: 3 }); +if (isMacintosh) { + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '2_open', + command: { + id: OpenFileFolderAction.ID, + title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...") + }, + order: 1 + }); +} else { + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '2_open', + command: { + id: OpenFileAction.ID, + title: nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...") + }, + order: 1 + }); + + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '2_open', + command: { + id: OpenFolderAction.ID, + title: nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...") + }, + order: 2 + }); +} + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '5_autosave', command: { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index a38fbde646df1..5d2bf42818483 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,7 +14,7 @@ import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; -import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, OpenFileFolderAction, OpenFileAction, OpenFolderAction, CloseWorkspaceAction, OpenLocalFileAction, OpenLocalFolderAction, OpenLocalFileFolderAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -35,16 +35,6 @@ import product from 'vs/platform/product/node/product'; (function registerFileActions(): void { const fileCategory = nls.localize('file', "File"); - if (isMacintosh) { - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileFolderAction, OpenFileFolderAction.ID, OpenFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileFolderAction, OpenLocalFileFolderAction.ID, OpenLocalFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local...', fileCategory); - } else { - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open File...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'File: Open Folder...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileAction, OpenLocalFileAction.ID, OpenLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local File...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFolderAction, OpenLocalFolderAction.ID, OpenLocalFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }, RemoteFileDialogContext), 'File: Open Local Folder...', fileCategory); - } - registry.registerWorkbenchAction(new SyncActionDescriptor(SaveLocalFileAction, SaveLocalFileAction.ID, SaveLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_S }, RemoteFileDialogContext), 'File: Save Local File...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenRecentAction, QuickOpenRecentAction.ID, QuickOpenRecentAction.LABEL), 'File: Quick Open Recent...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRecentAction, OpenRecentAction.ID, OpenRecentAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_R, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } }), 'File: Open Recent...', fileCategory); @@ -227,35 +217,6 @@ import product from 'vs/platform/product/node/product'; order: 2 }); - if (isMacintosh) { - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFileFolderAction.ID, - title: nls.localize({ key: 'miOpen', comment: ['&& denotes a mnemonic'] }, "&&Open...") - }, - order: 1 - }); - } else { - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFileAction.ID, - title: nls.localize({ key: 'miOpenFile', comment: ['&& denotes a mnemonic'] }, "&&Open File...") - }, - order: 1 - }); - - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenFolderAction.ID, - title: nls.localize({ key: 'miOpenFolder', comment: ['&& denotes a mnemonic'] }, "Open &&Folder...") - }, - order: 2 - }); - } - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '2_open', command: { From 927cc54293df53c52b26879795b996e3695c37ee Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 17:01:27 -0700 Subject: [PATCH 138/364] Basic file opening via Open File command --- src/vs/workbench/browser/web.simpleservices.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 055c006de7a69..353e4506be88d 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -45,6 +45,9 @@ import { CommentingRanges } from 'vs/editor/common/modes'; import { Range } from 'vs/editor/common/core/range'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; +import { pathsToEditors } from 'vs/workbench/common/editor'; +import { IFileService } from 'vs/platform/files/common/files'; //#region Backup File @@ -735,6 +738,12 @@ export class SimpleWindowService implements IWindowService { readonly windowId = 0; + constructor( + @IEditorService private readonly editorService: IEditorService, + @IFileService private readonly fileService: IFileService + ) { + } + isFocused(): Promise { return Promise.resolve(this.hasFocus); } @@ -849,15 +858,19 @@ export class SimpleWindowService implements IWindowService { return Promise.resolve(); } - openWindow(_uris: IURIToOpen[], _options?: IOpenSettings): Promise { + async openWindow(_uris: IURIToOpen[], _options?: IOpenSettings): Promise { // TODO: SUpport window.openFoldersInNewWindow setting - _uris.forEach(uri => { + _uris.forEach(async uri => { if ('folderUri' in uri) { window.open(`${document.location.origin}/?folder=${uri.folderUri.path}`); } if ('workspaceUri' in uri) { window.open(`${document.location.origin}/?folder=${uri.workspaceUri.path}`); } + if ('fileUri' in uri) { + const inputs: IResourceEditor[] = await pathsToEditors([uri], this.fileService); + this.editorService.openEditors(inputs); + } }); return Promise.resolve(); } From 21795f1f87fe34ba6e12a5e006263413d7435e8d Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 17:13:05 -0700 Subject: [PATCH 139/364] Update auto detect layout info. --- .../contrib/preferences/browser/keyboardLayoutPicker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 92c47b46e75cc..5b02583135d88 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -115,7 +115,7 @@ export class KeyboardLayoutPickerAction extends Action { return { label: layoutInfo.label, id: (layout).text || (layout).lang || (layout).layout, - description: layoutInfo.description + (picked ? ' (Current selection)' : ''), + description: layoutInfo.description + (picked ? ' (Current layout)' : ''), picked: !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout) }; }); @@ -132,7 +132,7 @@ export class KeyboardLayoutPickerAction extends Action { // Offer to "Auto Detect" const autoDetectMode: IQuickPickItem = { label: nls.localize('autoDetect', "Auto Detect"), - description: isAutoDetect ? `(Current: ${(currentLayout).text || (currentLayout).lang || (currentLayout).layout})` : undefined, + description: isAutoDetect ? `(Current: ${parseKeyboardLayout(currentLayout).label})` : undefined, picked: isAutoDetect ? true : undefined }; From 39d4aa8b2d4d990798cc3fd2dedcfcbcbd74376a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 17:17:44 -0700 Subject: [PATCH 140/364] Respect openFoldersInNewWindow setting for folders/workspaces --- .../workbench/browser/web.simpleservices.ts | 32 ++++++++++++++++--- .../browser/workbench.contribution.ts | 14 +++++++- .../electron-browser/main.contribution.ts | 12 ------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 353e4506be88d..9c5e7f441d098 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -26,7 +26,7 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IStorageService, IWorkspaceStorageChangeEvent, StorageScope, IWillSaveStateEvent, WillSaveStateReason } from 'vs/platform/storage/common/storage'; import { IUpdateService, State } from 'vs/platform/update/common/update'; -import { IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IURIToOpen, IMessageBoxResult, IWindowsService, IOpenSettings } from 'vs/platform/windows/common/windows'; +import { IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IURIToOpen, IMessageBoxResult, IWindowsService, IOpenSettings, IWindowSettings } from 'vs/platform/windows/common/windows'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, IWorkspaceFolderCreationData, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { IRecentlyOpened, IRecent } from 'vs/platform/history/common/history'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; @@ -48,6 +48,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { IEditorService, IResourceEditor } from 'vs/workbench/services/editor/common/editorService'; import { pathsToEditors } from 'vs/workbench/common/editor'; import { IFileService } from 'vs/platform/files/common/files'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; //#region Backup File @@ -740,7 +741,8 @@ export class SimpleWindowService implements IWindowService { constructor( @IEditorService private readonly editorService: IEditorService, - @IFileService private readonly fileService: IFileService + @IFileService private readonly fileService: IFileService, + @IConfigurationService private readonly configurationService: IConfigurationService ) { } @@ -859,13 +861,23 @@ export class SimpleWindowService implements IWindowService { } async openWindow(_uris: IURIToOpen[], _options?: IOpenSettings): Promise { - // TODO: SUpport window.openFoldersInNewWindow setting + const { openFolderInNewWindow } = this.shouldOpenNewWindow(_options); _uris.forEach(async uri => { if ('folderUri' in uri) { - window.open(`${document.location.origin}/?folder=${uri.folderUri.path}`); + const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}`; + if (openFolderInNewWindow) { + window.open(newAddress); + } else { + window.location.href = newAddress; + } } if ('workspaceUri' in uri) { - window.open(`${document.location.origin}/?folder=${uri.workspaceUri.path}`); + const newAddress = `${document.location.origin}/?workspace=${uri.workspaceUri.path}`; + if (openFolderInNewWindow) { + window.open(newAddress); + } else { + window.location.href = newAddress; + } } if ('fileUri' in uri) { const inputs: IResourceEditor[] = await pathsToEditors([uri], this.fileService); @@ -875,6 +887,16 @@ export class SimpleWindowService implements IWindowService { return Promise.resolve(); } + private shouldOpenNewWindow(_options: IOpenSettings = {}): { openFolderInNewWindow: boolean } { + const windowConfig = this.configurationService.getValue('window'); + const openFolderInNewWindowConfig = (windowConfig && windowConfig.openFoldersInNewWindow) || 'default' /* default */; + let openFolderInNewWindow = !!_options.forceNewWindow && !_options.forceReuseWindow; + if (!_options.forceNewWindow && !_options.forceReuseWindow && (openFolderInNewWindowConfig === 'on' || openFolderInNewWindowConfig === 'off')) { + openFolderInNewWindow = (openFolderInNewWindowConfig === 'on'); + } + return { openFolderInNewWindow }; + } + closeWindow(): Promise { return Promise.resolve(); } diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 5b46af70bad68..597d73d3e5a68 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -306,7 +306,19 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'scope': ConfigurationScope.APPLICATION, 'markdownDescription': nls.localize('disableCustomMenuBarAltFocus', "If enabled, disables the ability to focus the menu bar with the Alt-key when not set to toggle."), 'included': isWindows || isLinux || isWeb - } + }, + 'window.openFoldersInNewWindow': { + 'type': 'string', + 'enum': ['on', 'off', 'default'], + 'enumDescriptions': [ + nls.localize('window.openFoldersInNewWindow.on', "Folders will open in a new window."), + nls.localize('window.openFoldersInNewWindow.off', "Folders will replace the last active window."), + nls.localize('window.openFoldersInNewWindow.default', "Folders will open in a new window unless a folder is picked from within the application (e.g. via the File menu).") + ], + 'default': 'default', + 'scope': ConfigurationScope.APPLICATION, + 'markdownDescription': nls.localize('openFoldersInNewWindow', "Controls whether folders should open in a new window or replace the last active window.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") + }, } }); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 5d2bf42818483..e26745ef1caf5 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -487,18 +487,6 @@ import product from 'vs/platform/product/node/product'; nls.localize('openFilesInNewWindowMac', "Controls whether files should open in a new window. \nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") : nls.localize('openFilesInNewWindow', "Controls whether files should open in a new window.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") }, - 'window.openFoldersInNewWindow': { - 'type': 'string', - 'enum': ['on', 'off', 'default'], - 'enumDescriptions': [ - nls.localize('window.openFoldersInNewWindow.on', "Folders will open in a new window."), - nls.localize('window.openFoldersInNewWindow.off', "Folders will replace the last active window."), - nls.localize('window.openFoldersInNewWindow.default', "Folders will open in a new window unless a folder is picked from within the application (e.g. via the File menu).") - ], - 'default': 'default', - 'scope': ConfigurationScope.APPLICATION, - 'markdownDescription': nls.localize('openFoldersInNewWindow', "Controls whether folders should open in a new window or replace the last active window.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") - }, 'window.openWithoutArgumentsInNewWindow': { 'type': 'string', 'enum': ['on', 'off'], From 2ca61027e57930942c8f6da34031a3cc0009556c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 17:19:01 -0700 Subject: [PATCH 141/364] Make openWindow function resolve at right time --- src/vs/workbench/browser/web.simpleservices.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 9c5e7f441d098..ad5ffe6a2708d 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -862,7 +862,8 @@ export class SimpleWindowService implements IWindowService { async openWindow(_uris: IURIToOpen[], _options?: IOpenSettings): Promise { const { openFolderInNewWindow } = this.shouldOpenNewWindow(_options); - _uris.forEach(async uri => { + for (let i = 0; i < _uris.length; i++) { + const uri = _uris[i]; if ('folderUri' in uri) { const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}`; if (openFolderInNewWindow) { @@ -883,7 +884,7 @@ export class SimpleWindowService implements IWindowService { const inputs: IResourceEditor[] = await pathsToEditors([uri], this.fileService); this.editorService.openEditors(inputs); } - }); + } return Promise.resolve(); } From b26ee54a3ce361973f264a80146b3a18f5c14162 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 17:19:19 -0700 Subject: [PATCH 142/364] keyboard layout status bar item tooltip --- .../contrib/preferences/browser/keyboardLayoutPicker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 5b02583135d88..aeabf4a637f6b 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -63,8 +63,8 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), command: KEYBOARD_LAYOUT_OPEN_PICKER }, - 'status.editor.screenReaderMode', - nls.localize('status.editor.screenReaderMode', "Screen Reader Mode"), + 'status.workbench.keyboardLayout', + nls.localize('status.workbench.keyboardLayout', "Current keyboard layout"), StatusbarAlignment.RIGHT ); } From 960db12e86bcdc4ad61a8841052dbb956a23e8ac Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 17:22:56 -0700 Subject: [PATCH 143/364] Move workspace menu and action to fileActions.contribution --- .../files/browser/fileActions.contribution.ts | 15 ++++++++++++++- .../electron-browser/main.contribution.ts | 13 +------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 363a0c6233e25..8573f02c5a2aa 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -25,7 +25,7 @@ import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { SupportsWorkspacesContext, IsWebContext, RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { OpenFileFolderAction, OpenLocalFileFolderAction, OpenFileAction, OpenFolderAction, OpenLocalFileAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { OpenFileFolderAction, OpenLocalFileFolderAction, OpenFileAction, OpenFolderAction, OpenLocalFileAction, OpenLocalFolderAction, OpenWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; // Contribute Global Actions const category = { value: nls.localize('filesCategory', "File"), original: 'File' }; @@ -59,6 +59,9 @@ if (isMacintosh) { } } +const workspacesCategory = nls.localize('workspaces', "Workspaces"); +registry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Workspaces: Open Workspace...', workspacesCategory, SupportsWorkspacesContext); + // Commands CommandsRegistry.registerCommand('_files.windowOpen', openWindowCommand); CommandsRegistry.registerCommand('_files.newWindow', newWindowCommand); @@ -633,6 +636,16 @@ if (isMacintosh) { }); } +MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { + group: '2_open', + command: { + id: OpenWorkspaceAction.ID, + title: nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...") + }, + order: 3, + when: SupportsWorkspacesContext +}); + MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { group: '5_autosave', command: { diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index e26745ef1caf5..aa6647f914f6a 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,7 +14,7 @@ import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; -import { AddRootFolderAction, GlobalRemoveRootFolderAction, OpenWorkspaceAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; @@ -109,7 +109,6 @@ import product from 'vs/platform/product/node/product'; registry.registerWorkbenchAction(new SyncActionDescriptor(AddRootFolderAction, AddRootFolderAction.ID, AddRootFolderAction.LABEL), 'Workspaces: Add Folder to Workspace...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(GlobalRemoveRootFolderAction, GlobalRemoveRootFolderAction.ID, GlobalRemoveRootFolderAction.LABEL), 'Workspaces: Remove Folder from Workspace...', workspacesCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Workspaces: Open Workspace...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(SaveWorkspaceAsAction, SaveWorkspaceAsAction.ID, SaveWorkspaceAsAction.LABEL), 'Workspaces: Save Workspace As...', workspacesCategory, SupportsWorkspacesContext); registry.registerWorkbenchAction(new SyncActionDescriptor(DuplicateWorkspaceInNewWindowAction, DuplicateWorkspaceInNewWindowAction.ID, DuplicateWorkspaceInNewWindowAction.LABEL), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory); @@ -217,16 +216,6 @@ import product from 'vs/platform/product/node/product'; order: 2 }); - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { - group: '2_open', - command: { - id: OpenWorkspaceAction.ID, - title: nls.localize({ key: 'miOpenWorkspace', comment: ['&& denotes a mnemonic'] }, "Open Wor&&kspace...") - }, - order: 3, - when: SupportsWorkspacesContext - }); - MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, { title: nls.localize({ key: 'miOpenRecent', comment: ['&& denotes a mnemonic'] }, "Open &&Recent"), submenu: MenuId.MenubarRecentMenu, From 63bcdd8373390e97c957e0a4ed6d069669f09b59 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 19 Jun 2019 17:55:29 -0700 Subject: [PATCH 144/364] Add clarifying comment on instance service request events --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index e67c5dba9247f..312ea61b5d66e 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -21,6 +21,7 @@ export const ITerminalInstanceService = createDecorator; getXtermConstructor(): Promise; From 3399d30c701a8f5569220fa6356a86e27f51345a Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Wed, 19 Jun 2019 18:54:54 -0700 Subject: [PATCH 145/364] Fullscreen change event. --- src/vs/base/browser/dom.ts | 1 + src/vs/workbench/browser/web.main.ts | 8 ++++++++ src/vs/workbench/browser/web.simpleservices.ts | 10 +++------- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 265d69f85a261..3fb6d8b35fcea 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -857,6 +857,7 @@ export const EventType = { ERROR: 'error', RESIZE: 'resize', SCROLL: 'scroll', + FULLSCREEN_CHANGE: 'fullscreenchange', // Form SELECT: 'select', CHANGE: 'change', diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 6f1954ba2520a..d33b249cc98f9 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -36,6 +36,7 @@ import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; import { ProductService } from 'vs/platform/product/browser/productService'; +import { setFullscreen } from 'vs/base/browser/browser'; class CodeRendererMain extends Disposable { @@ -63,6 +64,13 @@ class CodeRendererMain extends Disposable { // Layout this._register(addDisposableListener(window, EventType.RESIZE, () => this.workbench.layout())); + this._register(addDisposableListener(document, EventType.FULLSCREEN_CHANGE, () => { + if (document.fullscreenElement || (document).webkitFullscreenElement) { + setFullscreen(true); + } else { + setFullscreen(false); + } + })); // Resource Loading this._register(new WebResources(services.serviceCollection.get(IFileService))); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 96d6991045614..fd3d7c637cc3a 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -788,17 +788,13 @@ export class SimpleWindowService implements IWindowService { if ((document).fullscreen !== undefined) { if (!(document).fullscreen) { - return (target).requestFullscreen().then(() => { - browser.setFullscreen(true); - }).catch(() => { + return (target).requestFullscreen().catch(() => { // if it fails, chromium throws an exception with error undefined. // re https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullscreen console.warn('Toggle Full Screen failed'); }); } else { - return document.exitFullscreen().then(() => { - browser.setFullscreen(false); - }).catch(() => { + return document.exitFullscreen().catch(() => { console.warn('Exit Full Screen failed'); }); } @@ -809,7 +805,7 @@ export class SimpleWindowService implements IWindowService { try { if (!(document).webkitIsFullScreen) { (target).webkitRequestFullscreen(); // it's async, but doesn't return a real promise. - browser.setFullscreen(true); + browser.setFullscreen(true); // we have to set this proactively because Safari doesn't emit fullscreenchange event. } else { (document).webkitExitFullscreen(); // it's async, but doesn't return a real promise. browser.setFullscreen(false); From c3fe2d8acde04e579880413ae4622a1f551efdcc Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Wed, 19 Jun 2019 11:22:39 -0700 Subject: [PATCH 146/364] Remove unneeded margin on settings editor scrollbar Fix #75724 --- .../contrib/preferences/browser/media/settingsEditor2.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css index 07a0d93e5a8ef..90f36055ccc29 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css @@ -237,8 +237,6 @@ } .settings-editor > .settings-body .settings-tree-container { - margin-right: 1px; - /* So the item doesn't blend into the edge of the view container */ margin-top: 14px; border-spacing: 0; border-collapse: separate; From 9c29fb87cd39d9a01ed7edfdad0f58dc65c78789 Mon Sep 17 00:00:00 2001 From: orange4glace Date: Thu, 20 Jun 2019 12:31:42 +0900 Subject: [PATCH 147/364] fix: #72626 --- src/vs/workbench/contrib/files/browser/views/explorerViewer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 184916e4ee56c..4592b3918ec9d 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -234,7 +234,7 @@ export class FilesRenderer implements ITreeRenderer editableData.onFinish(value, success), 0); }); @@ -265,6 +265,7 @@ export class FilesRenderer implements ITreeRenderer Date: Thu, 20 Jun 2019 09:34:03 +0200 Subject: [PATCH 148/364] Remove extra register of automatic tasks Fixes #75758 --- .../tasks/electron-browser/taskService.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts b/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts index 388846988a3dd..631275db0d0a1 100644 --- a/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts +++ b/src/vs/workbench/contrib/tasks/electron-browser/taskService.ts @@ -3,34 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; import * as Objects from 'vs/base/common/objects'; import * as semver from 'semver'; import { IStringDictionary } from 'vs/base/common/collections'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { ITaskSystem } from 'vs/workbench/contrib/tasks/common/taskSystem'; import { ExecutionEngine, TaskRunSource } from 'vs/workbench/contrib/tasks/common/tasks'; import * as TaskConfig from '../common/taskConfiguration'; import { ProcessTaskSystem } from 'vs/workbench/contrib/tasks/node/processTaskSystem'; import { ProcessRunnerDetector } from 'vs/workbench/contrib/tasks/node/processRunnerDetector'; -import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { RunAutomaticTasks, AllowAutomaticTaskRunning, DisallowAutomaticTaskRunning } from 'vs/workbench/contrib/tasks/browser/runAutomaticTasks'; import { AbstractTaskService } from 'vs/workbench/contrib/tasks/browser/abstractTaskService'; import { TaskFilter } from 'vs/workbench/contrib/tasks/common/taskService'; -let tasksCategory = nls.localize('tasksCategory', "Tasks"); - -const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); -workbenchRegistry.registerWorkbenchContribution(RunAutomaticTasks, LifecyclePhase.Eventually); - -const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowAutomaticTaskRunning, AllowAutomaticTaskRunning.ID, AllowAutomaticTaskRunning.LABEL), 'Tasks: Allow Automatic Tasks in Folder', tasksCategory); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowAutomaticTaskRunning, DisallowAutomaticTaskRunning.ID, DisallowAutomaticTaskRunning.LABEL), 'Tasks: Disallow Automatic Tasks in Folder', tasksCategory); - interface WorkspaceFolderConfigurationResult { workspaceFolder: IWorkspaceFolder; config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; From a9672ad7463fb16a03d7e3d9b5ea401227e930c1 Mon Sep 17 00:00:00 2001 From: ozyx Date: Thu, 20 Jun 2019 00:36:34 -0700 Subject: [PATCH 149/364] remove trailing '/' from repo url for baseFolderName --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index df9de2ad97415..30348608dd0b9 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -339,7 +339,7 @@ export class Git { } async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise { - let baseFolderName = decodeURI(url).replace(/^.*\//, '').replace(/\.git$/, '') || 'repository'; + let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*\//, '').replace(/\.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(parentPath, folderName); let count = 1; From 6c5bb443ac8c8233cabe3fab7d88a887bc9724f2 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 20 Jun 2019 09:38:42 +0200 Subject: [PATCH 150/364] handle style-attribute modifications, cache requests in addition to results, #75061 --- src/vs/workbench/browser/web.resources.ts | 98 +++++++++++++---------- 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/src/vs/workbench/browser/web.resources.ts b/src/vs/workbench/browser/web.resources.ts index 8d1d22a82646a..ca6c82ef78727 100644 --- a/src/vs/workbench/browser/web.resources.ts +++ b/src/vs/workbench/browser/web.resources.ts @@ -10,20 +10,25 @@ import { getMediaMime } from 'vs/base/common/mime'; export class WebResources { private readonly _regexp = /url\(('|")?(vscode-remote:\/\/.*?)\1\)/g; - private readonly _cache = new Map(); + private readonly _urlCache = new Map(); + private readonly _requestCache = new Map>(); private readonly _observer: MutationObserver; constructor(@IFileService private readonly _fileService: IFileService) { - this._observer = new MutationObserver(r => this._handleMutation(r)); - // todo@joh add observer to more than head-element // todo@joh explore alternative approach - this._observer.observe(document.head, { subtree: true, childList: true }); + this._observer = new MutationObserver(r => this._handleMutation(r)); + this._observer.observe(document, { + subtree: true, + childList: true, + attributes: true, + attributeFilter: ['style'] + }); } dispose(): void { this._observer.disconnect(); - this._cache.forEach(value => URL.revokeObjectURL(value)); + this._urlCache.forEach(value => URL.revokeObjectURL(value)); } private _handleMutation(records: MutationRecord[]): void { @@ -39,62 +44,73 @@ export class WebResources { this._handleStyleNode(node); } }); + } else if (record.type === 'attributes') { + // style-attribute + this._handleAttrMutation(record.target); } } } private _handleStyleNode(target: Node): void { + if (target.textContent && target.textContent.indexOf('vscode-remote://') >= 0) { + const content = target.textContent; + this._rewriteUrls(content).then(value => { + if (content === target.textContent) { + target.textContent = value; + } + }).catch(e => { + console.error(e); + }); + } + } - if (!target.textContent) { - return; + private _handleAttrMutation(target: Node): void { + const styleValue = (target).getAttribute('style'); + if (styleValue && styleValue.indexOf('vscode-remote://') >= 0) { + this._rewriteUrls(styleValue).then(value => { + if (value !== styleValue) { + (target).setAttribute('style', value); + } + }).catch(e => { + console.error(e); + }); } + } + + private async _rewriteUrls(textContent: string): Promise { const positions: number[] = []; const promises: Promise[] = []; let match: RegExpMatchArray | null = null; - while (match = this._regexp.exec(target.textContent)) { + while (match = this._regexp.exec(textContent)) { const remoteUrl = match[2]; positions.push(match.index! + 'url('.length + (typeof match[1] === 'string' ? match[1].length : 0)); positions.push(remoteUrl.length); - if (this._cache.has(remoteUrl)) { - promises.push(Promise.resolve()); - - } else { - const uri = URI.parse(remoteUrl, true); - promises.push(this._fileService.readFile(uri).then(file => { - this._cache.set(remoteUrl, URL.createObjectURL(new Blob( - [file.value.buffer], { type: getMediaMime(uri.path) } - ))); - })); + if (!this._urlCache.has(remoteUrl)) { + let request = this._requestCache.get(remoteUrl); + if (!request) { + const uri = URI.parse(remoteUrl, true); + request = this._fileService.readFile(uri).then(file => { + const blobUrl = URL.createObjectURL(new Blob([file.value.buffer], { type: getMediaMime(uri.path) })); + this._urlCache.set(remoteUrl, blobUrl); + }); + this._requestCache.set(remoteUrl, request); + } + promises.push(request); } } - if (promises.length === 0) { - return; + let content = textContent; + await Promise.all(promises); + for (let i = positions.length - 1; i >= 0; i -= 2) { + const start = positions[i - 1]; + const len = positions[i]; + const url = this._urlCache.get(content.substr(start, len)); + content = content.substring(0, start) + url + content.substring(start + len); } - - let content = target.textContent; - - Promise.all(promises).then(() => { - - if (target.textContent !== content) { - return; - } - - for (let i = positions.length - 1; i >= 0; i -= 2) { - const start = positions[i - 1]; - const len = positions[i]; - const url = this._cache.get(content.substr(start, len)); - content = content.substring(0, start) + url + content.substring(start + len); - } - - target.textContent = content; - - }).catch(e => { - console.error(e); - }); + return content; } } From 49e75c37a48b89df58409f4568409d3f0073d09d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 20 Jun 2019 09:50:42 +0200 Subject: [PATCH 151/364] fix #75818 --- src/vs/editor/contrib/suggest/suggestWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/suggest/suggestWidget.ts b/src/vs/editor/contrib/suggest/suggestWidget.ts index d3089cd14287b..7dabc8b16a5c1 100644 --- a/src/vs/editor/contrib/suggest/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/suggestWidget.ts @@ -956,7 +956,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate Date: Thu, 20 Jun 2019 09:51:21 +0200 Subject: [PATCH 152/364] fix bad tree guide indentation --- src/vs/base/browser/ui/tree/media/tree.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 564d5505e4163..85dcafe22b1bd 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -27,6 +27,11 @@ body:not([data-exploration="icon-exploration"]) .monaco-tl-indent { left: 16px; } +/* TODO @misolori remove before shipping stable */ +body:not([data-exploration="icon-exploration"]) .hide-arrows .monaco-tl-indent { + left: 10px; +} + .monaco-tl-indent > svg { overflow: visible; } From 7e1418779cdc0536d08ae8e6ed21f347a32bffcb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 10:03:02 +0200 Subject: [PATCH 153/364] remove TODO --- src/vs/code/electron-main/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index c5e45863a06db..a829266dc516c 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -523,7 +523,7 @@ export class CodeApplication extends Disposable { this.lifecycleService.phase = LifecycleMainPhase.Ready; // Propagate to clients - const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // TODO@Joao: unfold this + const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // Create a URL handler which forwards to the last active window const activeWindowManager = new ActiveWindowManager(windowsService); From 05ba8ae885c75c321ce5beabdf28bcb6be75c464 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 10:15:27 +0200 Subject: [PATCH 154/364] update eslint --- package.json | 2 +- yarn.lock | 379 ++++++++++++++++++--------------------------------- 2 files changed, 137 insertions(+), 244 deletions(-) diff --git a/package.json b/package.json index 770f731ec1b73..2b16c7a34e8a2 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "debounce": "^1.0.0", "documentdb": "^1.5.1", "electron-mksnapshot": "~2.0.0", - "eslint": "^3.4.0", + "eslint": "^4.18.2", "event-stream": "3.3.4", "express": "^4.13.1", "fancy-log": "^1.3.3", diff --git a/yarn.lock b/yarn.lock index a48125a4d72c1..4d4f75a05f7d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -303,10 +303,10 @@ acorn@^5.0.0, acorn@^5.6.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" integrity sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ== -acorn@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" - integrity sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w== +acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== acorn@^6.0.2: version "6.0.7" @@ -327,24 +327,16 @@ agent-base@~4.2.0: dependencies: es6-promisify "^5.0.0" -ajv-keywords@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" - integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= -ajv@^4.7.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - ajv@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda" @@ -355,7 +347,7 @@ ajv@^5.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^5.3.0: +ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= @@ -423,11 +415,6 @@ ansi-cyan@^0.1.1: dependencies: ansi-wrap "0.1.0" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -828,7 +815,7 @@ azure-storage@^2.10.2: xml2js "0.2.8" xmlbuilder "^9.0.7" -babel-code-frame@^6.16.0: +babel-code-frame@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= @@ -1309,7 +1296,7 @@ chalk@2.3.1: escape-string-regexp "^1.0.5" supports-color "^5.2.0" -chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -1347,6 +1334,11 @@ chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + chardet@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" @@ -1473,13 +1465,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= - dependencies: - restore-cursor "^1.0.1" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -1720,7 +1705,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@1.6.0, concat-stream@^1.5.2: +concat-stream@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" integrity sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc= @@ -1894,7 +1879,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@^5.0.1: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= @@ -2083,7 +2068,7 @@ debug@2.2.0: dependencies: ms "0.7.1" -debug@2.6.9, debug@^2.1.1, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2319,14 +2304,6 @@ dir-glob@^2.0.0: arrify "^1.0.1" path-type "^3.0.0" -doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" - integrity sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -2592,18 +2569,6 @@ es6-iterator@^2.0.1, es6-iterator@~2.0.1: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - es6-promise@^4.0.3: version "4.2.4" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" @@ -2616,18 +2581,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: +es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= @@ -2684,13 +2638,11 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" esrecurse "^4.1.0" estraverse "^4.1.1" @@ -2712,46 +2664,49 @@ eslint-visitor-keys@^1.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== -eslint@^3.4.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" - integrity sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw= +eslint@^4.18.2: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== dependencies: - babel-code-frame "^6.16.0" - chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" - doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" esquery "^1.0.0" - estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" + inquirer "^3.0.6" is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" strip-json-comments "~2.0.1" - table "^3.7.8" + table "4.0.2" text-table "~0.2.0" - user-home "^2.0.0" eslint@^5.0.1: version "5.13.0" @@ -2795,12 +2750,12 @@ eslint@^5.0.1: table "^5.0.2" text-table "^0.2.0" -espree@^3.4.0: - version "3.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" - integrity sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ== +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== dependencies: - acorn "^5.2.1" + acorn "^5.5.0" acorn-jsx "^3.0.0" espree@^5.0.0: @@ -2859,7 +2814,7 @@ estraverse@^1.9.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= @@ -2874,14 +2829,6 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= - dependencies: - d "1" - es5-ext "~0.10.14" - event-stream@3.3.4, event-stream@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -2939,11 +2886,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= - expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -3051,6 +2993,15 @@ extend@^3.0.2, extend@~3.0.2: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + external-editor@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.0.tgz#dc35c48c6f98a30ca27a20e9687d7f3c77704bb6" @@ -3177,14 +3128,6 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3712,7 +3655,7 @@ glob@^6.0.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: +glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== @@ -3761,16 +3704,16 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" +globals@^11.0.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + globals@^11.7.0: version "11.10.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50" integrity sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ== -globals@^9.14.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -4393,7 +4336,7 @@ iconv-lite@0.4.23, iconv-lite@^0.4.22, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.4.24: +iconv-lite@^0.4.17, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -4417,12 +4360,7 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" -ignore@^3.2.0: - version "3.3.7" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" - integrity sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA== - -ignore@^3.3.5: +ignore@^3.3.3, ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== @@ -4498,23 +4436,24 @@ innosetup@5.6.1: resolved "https://registry.yarnpkg.com/innosetup/-/innosetup-5.6.1.tgz#6e7031ba35b23e716e4f29686bc994052e0c278c" integrity sha512-Eit24N3JR8O0Wpuq/dMWCl2r550eiNP2124SbdbwOob43x89WPGL/SGpZG5EPHu20kV2N+4TwvHwFIM8pFUJ0g== -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" - integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34= +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" cli-width "^2.0.0" - figures "^1.3.5" + external-editor "^2.0.4" + figures "^2.0.0" lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" through "^2.3.6" inquirer@^6.0.0: @@ -4560,11 +4499,6 @@ int64-buffer@^0.1.9: resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.9.tgz#9e039da043b24f78b196b283e04653ef5e990f61" integrity sha1-ngOdoEOyT3ixlrKD4EZT716ZD2E= -interpret@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" - integrity sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA= - interpret@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" @@ -4762,7 +4696,7 @@ is-glob@^4.0.0: dependencies: is-extglob "^2.1.1" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: +is-my-json-valid@^2.12.4: version "2.16.1" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" integrity sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ== @@ -5056,7 +4990,7 @@ js-yaml@3.6.1: argparse "^1.0.7" esprima "^2.6.0" -js-yaml@3.x, js-yaml@^3.5.1: +js-yaml@3.x: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" integrity sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA== @@ -5072,7 +5006,7 @@ js-yaml@^3.12.0: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.13.0: +js-yaml@^3.13.0, js-yaml@^3.9.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -5145,7 +5079,7 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= @@ -5439,7 +5373,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.0.0, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.3.0: +lodash@^4.13.1, lodash@^4.15.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= @@ -5965,11 +5899,6 @@ mute-stdout@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" - integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= - mute-stream@0.0.7, mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -6384,11 +6313,6 @@ once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= - onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -6847,10 +6771,10 @@ plugin-error@1.0.1, plugin-error@^1.0.1: arr-union "^3.1.0" extend-shallow "^3.0.2" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" - integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== portfinder@^1.0.13: version "1.0.20" @@ -7535,15 +7459,6 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -7591,6 +7506,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -7769,7 +7689,7 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-uncached@^1.0.2: +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= @@ -7843,14 +7763,6 @@ resolve@^1.4.0: dependencies: path-parse "^1.0.6" -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -7905,13 +7817,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" - integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k= - dependencies: - once "^1.3.0" - run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -7926,10 +7831,17 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" - integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= rxjs@^6.1.0: version "6.2.2" @@ -8126,15 +8038,6 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM= - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - sigmund@^1.0.1, sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" @@ -8181,10 +8084,12 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" slice-ansi@^2.0.0: version "2.1.0" @@ -8572,11 +8477,6 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -8665,17 +8565,17 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" - integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8= +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" table@^5.0.2: version "5.2.2" @@ -9279,13 +9179,6 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= - dependencies: - os-homedir "^1.0.0" - util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" From 9d82f43b78eea79a9160fa7c338b64e3989b9993 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 10:20:03 +0200 Subject: [PATCH 155/364] update distro fixes #73872 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b16c7a34e8a2..892fac7ab0d7c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "555abb7db38aa08e0f905213c013f7bad0747ed2", + "distro": "cb7eed7b39c86ccca67c4359cba49df01709d5ed", "author": { "name": "Microsoft Corporation" }, From bbb45622d8b857fabb75631d66f2b21fc47f1095 Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 20 Jun 2019 10:26:48 +0200 Subject: [PATCH 156/364] Revert "Revert "Merge pull request #75695 from orange4glace/master"" This reverts commit a05e05ca19f6e82d0d90c54029a8b76e4ed5896a. --- .../files/browser/views/explorerViewer.ts | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 76fab05327567..184916e4ee56c 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -218,22 +218,29 @@ export class FilesRenderer implements ITreeRenderer 0 && !stat.isDirectory ? lastDot : value.length }); - const done = once(async (success: boolean, finishEditing: boolean) => { + let isFinishableDisposeEvent = false; + setTimeout(() => { + // Check if disposed + if (!inputBox.inputElement) { + return; + } + inputBox.focus(); + inputBox.select({ start: 0, end: lastDot > 0 && !stat.isDirectory ? lastDot : value.length }); + isFinishableDisposeEvent = true; + }, 0); + + const done = once(async (success: boolean) => { label.element.style.display = 'none'; const value = inputBox.value; dispose(toDispose); container.removeChild(label.element); - if (finishEditing) { - // Timeout: once done rendering only then re-render #70902 - setTimeout(() => editableData.onFinish(value, success), 0); - } + // Timeout: once done rendering only then re-render #70902 + setTimeout(() => editableData.onFinish(value, success), 0); }); const blurDisposable = DOM.addDisposableListener(inputBox.inputElement, DOM.EventType.BLUR, () => { - done(inputBox.isInputValid(), true); + done(inputBox.isInputValid()); }); const toDispose = [ @@ -241,10 +248,10 @@ export class FilesRenderer implements ITreeRenderer { if (e.equals(KeyCode.Enter)) { if (inputBox.validate()) { - done(true, true); + done(true); } } else if (e.equals(KeyCode.Escape)) { - done(false, true); + done(false); } }), blurDisposable, @@ -253,8 +260,12 @@ export class FilesRenderer implements ITreeRenderer { - blurDisposable.dispose(); - done(false, false); + if (isFinishableDisposeEvent) { + done(false); + } + else { + dispose(toDispose); + } }); } From db17c23a72e9dd57da6f7b53d006832f791369ed Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 20 Jun 2019 10:27:01 +0200 Subject: [PATCH 157/364] Revert "Revert "explorero: file actions disablment no longer needed"" This reverts commit b6341520000c2615b9f0cb4aad732216826d0bc4. --- .../contrib/files/browser/fileActions.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index f12976ad42cb4..837f66be83b71 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -85,15 +85,10 @@ export class NewFileAction extends Action { static readonly LABEL = nls.localize('createNewFile', "New File"); constructor( - @IExplorerService explorerService: IExplorerService, @ICommandService private commandService: ICommandService ) { super('explorer.newFile', NEW_FILE_LABEL); this.class = 'explorer-action new-file'; - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } run(): Promise { @@ -107,15 +102,10 @@ export class NewFolderAction extends Action { static readonly LABEL = nls.localize('createNewFolder', "New Folder"); constructor( - @IExplorerService explorerService: IExplorerService, @ICommandService private commandService: ICommandService ) { super('explorer.newFolder', NEW_FOLDER_LABEL); this.class = 'explorer-action new-folder'; - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } run(): Promise { @@ -609,10 +599,6 @@ export class CollapseExplorerView extends Action { @IExplorerService readonly explorerService: IExplorerService ) { super(id, label, 'explorer-action collapse-explorer'); - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } run(): Promise { @@ -637,10 +623,6 @@ export class RefreshExplorerView extends Action { @IExplorerService private readonly explorerService: IExplorerService ) { super(id, label, 'explorer-action refresh-explorer'); - this._register(explorerService.onDidChangeEditable(e => { - const elementIsBeingEdited = explorerService.isEditable(e); - this.enabled = !elementIsBeingEdited; - })); } public run(): Promise { From 5c3bab92ac05e8e1fb33d77fad154f4314d39f14 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 20 Jun 2019 10:30:11 +0200 Subject: [PATCH 158/364] more code insets API tweaks, #66418 --- src/vs/vscode.proposed.d.ts | 5 +++-- .../workbench/api/browser/mainThreadCodeInsets.ts | 14 +++++++------- src/vs/workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostCodeInsets.ts | 8 ++++---- src/vs/workbench/api/node/extHost.api.impl.ts | 4 ++-- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 16e52984ff999..f7e2713eb471a 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -139,14 +139,15 @@ declare module 'vscode' { export interface WebviewEditorInset { readonly editor: TextEditor; - readonly range: Range; + readonly line: number; + readonly height: number; readonly webview: Webview; readonly onDidDispose: Event; dispose(): void; } export namespace window { - export function createWebviewTextEditorInset(editor: TextEditor, range: Range, options?: WebviewOptions): WebviewEditorInset; + export function createWebviewTextEditorInset(editor: TextEditor, line: number, height: number, options?: WebviewOptions): WebviewEditorInset; } //#endregion diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index 8fb66ec1a554c..378fb000ddbdb 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -7,7 +7,6 @@ import { UriComponents, URI } from 'vs/base/common/uri'; import * as modes from 'vs/editor/common/modes'; import { MainContext, MainThreadEditorInsetsShape, IExtHostContext, ExtHostEditorInsetsShape, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from '../common/extHostCustomers'; -import { IRange } from 'vs/editor/common/core/range'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; import { DisposableStore } from 'vs/base/common/lifecycle'; @@ -32,14 +31,15 @@ class EditorWebviewZone implements IViewZone { constructor( readonly editor: IActiveCodeEditor, - readonly range: IRange, + readonly line: number, + readonly height: number, readonly webview: Webview, ) { this.domNode = document.createElement('div'); this.domNode.style.zIndex = '10'; // without this, the webview is not interactive - this.afterLineNumber = range.startLineNumber; - this.afterColumn = range.startColumn; - this.heightInLines = range.endLineNumber - range.startLineNumber; + this.afterLineNumber = line; + this.afterColumn = 1; + this.heightInLines = height; editor.changeViewZones(accessor => this._id = accessor.addZone(this)); webview.mountTo(this.domNode); @@ -69,7 +69,7 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { this._disposables.dispose(); } - async $createEditorInset(handle: number, id: string, uri: UriComponents, range: IRange, options: modes.IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise { + async $createEditorInset(handle: number, id: string, uri: UriComponents, line: number, height: number, options: modes.IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise { let editor: IActiveCodeEditor | undefined; id = id.substr(0, id.indexOf(',')); //todo@joh HACK @@ -97,7 +97,7 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { localResourceRoots: options.localResourceRoots ? options.localResourceRoots.map(uri => URI.revive(uri)) : undefined }); - const webviewZone = new EditorWebviewZone(editor, range, webview); + const webviewZone = new EditorWebviewZone(editor, line, height, webview); const remove = () => { disposables.dispose(); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 375d760db516c..a26b979606ef8 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -511,7 +511,7 @@ export interface MainThreadTelemetryShape extends IDisposable { } export interface MainThreadEditorInsetsShape extends IDisposable { - $createEditorInset(handle: number, id: string, uri: UriComponents, range: IRange, options: modes.IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise; + $createEditorInset(handle: number, id: string, uri: UriComponents, line: number, height: number, options: modes.IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise; $disposeEditorInset(handle: number): void; $setHtml(handle: number, value: string): void; diff --git a/src/vs/workbench/api/common/extHostCodeInsets.ts b/src/vs/workbench/api/common/extHostCodeInsets.ts index 975f4ec205dcd..398afff564f61 100644 --- a/src/vs/workbench/api/common/extHostCodeInsets.ts +++ b/src/vs/workbench/api/common/extHostCodeInsets.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { Emitter } from 'vs/base/common/event'; -import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters'; import * as vscode from 'vscode'; import { MainThreadEditorInsetsShape } from './extHost.protocol'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; @@ -39,7 +38,7 @@ export class ExtHostEditorInsets implements ExtHostEditorInsets { this._disposables.dispose(); } - createWebviewEditorInset(editor: vscode.TextEditor, range: vscode.Range, options: vscode.WebviewOptions | undefined, extension: IExtensionDescription): vscode.WebviewEditorInset { + createWebviewEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions | undefined, extension: IExtensionDescription): vscode.WebviewEditorInset { let apiEditor: ExtHostTextEditor | undefined; for (const candidate of this._editors.getVisibleTextEditors()) { @@ -92,7 +91,8 @@ export class ExtHostEditorInsets implements ExtHostEditorInsets { const inset = new class implements vscode.WebviewEditorInset { readonly editor: vscode.TextEditor = editor; - readonly range: vscode.Range = range; + readonly line: number = line; + readonly height: number = height; readonly webview: vscode.Webview = webview; readonly onDidDispose: vscode.Event = onDidDispose.event; @@ -109,7 +109,7 @@ export class ExtHostEditorInsets implements ExtHostEditorInsets { } }; - this._proxy.$createEditorInset(handle, apiEditor.id, apiEditor.document.uri, typeConverters.Range.from(range), options || {}, extension.identifier, extension.extensionLocation); + this._proxy.$createEditorInset(handle, apiEditor.id, apiEditor.document.uri, line + 1, height, options || {}, extension.identifier, extension.extensionLocation); this._insets.set(handle, { editor, inset, onDidReceiveMessage }); return inset; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 9b23ac7027e37..0c1ccf3189042 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -505,9 +505,9 @@ export function createApiFactory( createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options); }, - createWebviewTextEditorInset(editor: vscode.TextEditor, range: vscode.Range, options: vscode.WebviewOptions): vscode.WebviewEditorInset { + createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions): vscode.WebviewEditorInset { checkProposedApiEnabled(extension); - return extHostEditorInsets.createWebviewEditorInset(editor, range, options, extension); + return extHostEditorInsets.createWebviewEditorInset(editor, line, height, options, extension); }, createTerminal(nameOrOptions?: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { if (typeof nameOrOptions === 'object') { From c6a21162350f3aa71c06d9ed9cafff6de982ac5e Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 20 Jun 2019 10:45:10 +0200 Subject: [PATCH 159/364] Alpine build --- build/azure-pipelines/linux/build-alpine.sh | 3 + .../azure-pipelines/linux/prebuild-alpine.sh | 3 + .../linux/product-build-linux-alpine.yml | 65 +++++++++++++++++++ build/azure-pipelines/linux/publish-alpine.sh | 3 + build/azure-pipelines/product-build.yml | 11 ++++ build/gulpfile.reh.js | 14 ++++ 6 files changed, 99 insertions(+) create mode 100755 build/azure-pipelines/linux/build-alpine.sh create mode 100755 build/azure-pipelines/linux/prebuild-alpine.sh create mode 100644 build/azure-pipelines/linux/product-build-linux-alpine.yml create mode 100755 build/azure-pipelines/linux/publish-alpine.sh diff --git a/build/azure-pipelines/linux/build-alpine.sh b/build/azure-pipelines/linux/build-alpine.sh new file mode 100755 index 0000000000000..4f01bc9a7e5d5 --- /dev/null +++ b/build/azure-pipelines/linux/build-alpine.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/prebuild-alpine.sh b/build/azure-pipelines/linux/prebuild-alpine.sh new file mode 100755 index 0000000000000..4f01bc9a7e5d5 --- /dev/null +++ b/build/azure-pipelines/linux/prebuild-alpine.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/linux/product-build-linux-alpine.yml b/build/azure-pipelines/linux/product-build-linux-alpine.yml new file mode 100644 index 0000000000000..4beee37d1a041 --- /dev/null +++ b/build/azure-pipelines/linux/product-build-linux-alpine.yml @@ -0,0 +1,65 @@ +steps: +- task: NodeTool@0 + inputs: + versionSpec: "10.15.1" + +- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.10.1" + +- task: AzureKeyVault@1 + displayName: 'Azure Key Vault: Get Secrets' + inputs: + azureSubscription: 'vscode-builds-subscription' + KeyVaultName: vscode + +- task: Docker@1 + displayName: 'Pull image' + inputs: + azureSubscriptionEndpoint: 'vscode-builds-subscription' + azureContainerRegistry: vscodehub.azurecr.io + command: 'Run an image' + imageName: 'vscode-linux-build-agent:alpine' + containerCommand: uname + +- script: | + set -e + + cat << EOF > ~/.netrc + machine monacotools.visualstudio.com + password $(devops-pat) + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF + + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" + git fetch distro + git merge $(node -p "require('./package.json').distro") + + CHILD_CONCURRENCY=1 yarn + yarn gulp mixin + yarn gulp hygiene + yarn monaco-compile-check + ./build/azure-pipelines/linux/prebuild-alpine.sh + displayName: Prepare build + +- script: | + set -e + ./build/azure-pipelines/linux/build-alpine.sh + displayName: Build + +- script: | + set -e + AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ + AZURE_STORAGE_ACCESS_KEY_2="$(vscode-storage-key)" \ + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + VSCODE_HOCKEYAPP_TOKEN="$(vscode-hockeyapp-token)" \ + ./build/azure-pipelines/linux/publish-alpine.sh + displayName: Publish + +- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + displayName: 'Component Detection' + continueOnError: true \ No newline at end of file diff --git a/build/azure-pipelines/linux/publish-alpine.sh b/build/azure-pipelines/linux/publish-alpine.sh new file mode 100755 index 0000000000000..4f01bc9a7e5d5 --- /dev/null +++ b/build/azure-pipelines/linux/publish-alpine.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +set -e +echo 'noop' \ No newline at end of file diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 590ac0dbed73b..25c572cfd5668 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -60,6 +60,16 @@ jobs: steps: - template: linux/product-build-linux-arm.yml +- job: LinuxAlpine + condition: eq(variables['VSCODE_BUILD_LINUX_ALPINE'], 'true') + timeoutInMinutes: 120 + pool: + vmImage: 'Ubuntu-16.04' + variables: + VSCODE_ARCH: alpine + steps: + - template: linux/product-build-linux-alpine.yml + - job: macOS condition: eq(variables['VSCODE_BUILD_MACOS'], 'true') timeoutInMinutes: 120 @@ -79,6 +89,7 @@ jobs: - Linux - LinuxSnap - LinuxArmhf + - LinuxAlpine - macOS steps: - template: sync-mooncake.yml \ No newline at end of file diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index b0e919883c460..afdd7e36f4cb4 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -8,6 +8,7 @@ const gulp = require('gulp'); const path = require('path'); +const cp = require('child_process'); const es = require('event-stream'); const util = require('./lib/util'); const task = require('./lib/task'); @@ -30,6 +31,7 @@ gulp.task('vscode-reh-win32-x64-min', noop); gulp.task('vscode-reh-darwin-min', noop); gulp.task('vscode-reh-linux-x64-min', noop); gulp.task('vscode-reh-linux-armhf-min', noop); +gulp.task('vscode-reh-linux-alpine-min', noop); function getNodeVersion() { @@ -86,6 +88,18 @@ function nodejs(platform, arch) { ); } + if (arch === 'alpine') { + return es.readArray([ + new File({ + path: 'node', + contents: cp.execSync(`docker run --rm node:${VERSION}-alpine /bin/sh -c 'cat \`which node\`'`, { maxBuffer: 100 * 1024 * 1024, encoding: 'buffer' }), + stat: { + mode: parseInt('755', 8) + } + }) + ]); + } + if (platform === 'darwin') { arch = 'x64'; } From 1051f38c737187a944b982c7bcb2e3533d9bed7b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 20 Jun 2019 10:56:30 +0200 Subject: [PATCH 160/364] Update distro hash --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 892fac7ab0d7c..7f473c58396d3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "cb7eed7b39c86ccca67c4359cba49df01709d5ed", + "distro": "336a0c632c464d9c81e6fbff00154852967eaf02", "author": { "name": "Microsoft Corporation" }, From 0361e0504145957522e59c8e9338d6c3666d98ad Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 20 Jun 2019 11:01:34 +0200 Subject: [PATCH 161/364] Remove duplicate cp --- build/gulpfile.reh.js | 1 - 1 file changed, 1 deletion(-) diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index afdd7e36f4cb4..2773a8cb43067 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -8,7 +8,6 @@ const gulp = require('gulp'); const path = require('path'); -const cp = require('child_process'); const es = require('event-stream'); const util = require('./lib/util'); const task = require('./lib/task'); From e82130da4bed64b76747ce56e5dceb6503ffc83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C4=8C=C3=A1bera?= Date: Thu, 20 Jun 2019 11:13:15 +0200 Subject: [PATCH 162/364] shellscript: Add folding markers --- extensions/shellscript/language-configuration.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/extensions/shellscript/language-configuration.json b/extensions/shellscript/language-configuration.json index 01b6a8a28239e..964623ac4cc15 100644 --- a/extensions/shellscript/language-configuration.json +++ b/extensions/shellscript/language-configuration.json @@ -22,5 +22,11 @@ ["\"", "\""], ["'", "'"], ["`", "`"] - ] -} \ No newline at end of file + ], + "folding": { + "markers": { + "start": "^\\s*#\\s*#?region\\b.*", + "end": "^\\s*#\\s*#?endregion\\b.*" + } + } +} From 983069b176088a3b62fc19dcfd2228af9143b746 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 11:47:09 +0200 Subject: [PATCH 163/364] fixes #75829 --- src/vs/platform/update/node/update.config.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 541ae043f9711..9d9507c6ce99e 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -38,7 +38,8 @@ configurationRegistry.registerConfiguration({ type: 'boolean', default: true, scope: ConfigurationScope.APPLICATION, - description: localize('enableWindowsBackgroundUpdates', "Enables Windows background updates. The updates are fetched from a Microsoft online service."), + title: localize('enableWindowsBackgroundUpdatesTitle', "Enable Background Updates on Windows"), + description: localize('enableWindowsBackgroundUpdates', "Enable to download and install new VS Code Versions in the background on Windows"), tags: ['usesOnlineServices'] }, 'update.showReleaseNotes': { From 6326c5d6b6611ce09a6bf0037e284e56701c0059 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 11:56:00 +0200 Subject: [PATCH 164/364] show setting on windows only --- src/vs/platform/update/node/update.config.contribution.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 9d9507c6ce99e..26e63ea0fe81b 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -6,6 +6,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { localize } from 'vs/nls'; +import { isWindows } from 'vs/base/common/platform'; const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); configurationRegistry.registerConfiguration({ @@ -40,7 +41,8 @@ configurationRegistry.registerConfiguration({ scope: ConfigurationScope.APPLICATION, title: localize('enableWindowsBackgroundUpdatesTitle', "Enable Background Updates on Windows"), description: localize('enableWindowsBackgroundUpdates', "Enable to download and install new VS Code Versions in the background on Windows"), - tags: ['usesOnlineServices'] + tags: ['usesOnlineServices'], + included: isWindows }, 'update.showReleaseNotes': { type: 'boolean', From e1ac9a2490eff941c56f666800e29987c7276a67 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 20 Jun 2019 12:31:09 +0200 Subject: [PATCH 165/364] add ExtensionKind and remoteName propsed APIs, #74188 --- src/vs/vscode.proposed.d.ts | 48 +++++++++++++++++-- .../workbench/api/common/extHost.protocol.ts | 2 +- .../api/common/extHostExtensionActivator.ts | 5 +- src/vs/workbench/api/common/extHostMemento.ts | 10 ++-- src/vs/workbench/api/common/extHostTypes.ts | 5 ++ src/vs/workbench/api/node/extHost.api.impl.ts | 21 ++++++-- .../api/node/extHostExtensionService.ts | 11 +++-- .../common/remoteExtensionHostClient.ts | 5 +- .../electron-browser/extensionHost.ts | 4 ++ .../node/extensionHostProcessSetup.ts | 4 +- 10 files changed, 92 insertions(+), 23 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index f7e2713eb471a..29764773871ac 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -17,18 +17,58 @@ declare module 'vscode' { //#region Joh - ExecutionContext - + // THIS is a deprecated proposal export enum ExtensionExecutionContext { Local = 1, Remote = 2 } + export interface ExtensionContext { + executionContext: ExtensionExecutionContext; + } + //#endregion + + //#region Joh - ExtensionKind, vscode.env.remoteKind + + /** + * In a remote window the extension kind describes if an extension + * runs where the UI (window) runs or if an extension runs remotely. + */ + export enum ExtensionKind { + + /** + * Extension runs where the UI runs. + */ + UI = 1, + + /** + * Extension runs where the remote extension host runs. + */ + Workspace = 2 + } export interface ExtensionContext { + /** - * Describes the context in which this extension is executed, e.g. - * a Node.js-context on the same machine or on a remote machine + * The extension kind describes if an extension runs where the UI runs + * or if an extension runs where the remote extension host runs. The extension kind + * if defined in the `package.json` file of extensions but can also be refined + * via the the `remote.extensionKind`-setting. When no remote extension host exists, + * the value is [`ExtensionKind.UI`](#ExtensionKind.UI). */ - executionContext: ExtensionExecutionContext; + extensionKind: ExtensionKind; + } + + export namespace env { + /** + * The name of a remote. Defined by extensions, popular samples are `wsl` for the Windows + * Subsystem for Linux or `ssh` for remotes using a secure shell. + * + * *Note* that the value is `undefined` when there is no remote extension host but that the + * value is defined in all extension hosts (local and remote) in case a remote extension host + * exists. Use [`ExtensionContext#extensionKind`](#ExtensionContext.extensionKind) to know if + * a specific extension runs remote or not. + */ + export const remoteName: string | undefined; } //#endregion diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index a26b979606ef8..df31280ffc898 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -85,7 +85,7 @@ export interface IInitData { logLevel: LogLevel; logsLocation: URI; autoStart: boolean; - remoteAuthority?: string | null; + remote: { isRemote: boolean; authority: string | undefined; }; } export interface IConfigurationInitData extends IConfigurationData { diff --git a/src/vs/workbench/api/common/extHostExtensionActivator.ts b/src/vs/workbench/api/common/extHostExtensionActivator.ts index 86d4926145683..b38a447ab685f 100644 --- a/src/vs/workbench/api/common/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/common/extHostExtensionActivator.ts @@ -8,12 +8,14 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ExtensionActivationError, MissingDependencyError } from 'vs/workbench/services/extensions/common/extensions'; +import { ExtensionKind } from 'vs/workbench/api/common/extHostTypes'; const NO_OP_VOID_PROMISE = Promise.resolve(undefined); export interface IExtensionMemento { + get(key: string): T | undefined; get(key: string, defaultValue: T): T; - update(key: string, value: any): Promise; + update(key: string, value: any): Promise; } export interface IExtensionContext { @@ -26,6 +28,7 @@ export interface IExtensionContext { asAbsolutePath(relativePath: string): string; readonly logPath: string; executionContext: number; + extensionKind: ExtensionKind; } /** diff --git a/src/vs/workbench/api/common/extHostMemento.ts b/src/vs/workbench/api/common/extHostMemento.ts index 3921d40d632d1..4502bacd67120 100644 --- a/src/vs/workbench/api/common/extHostMemento.ts +++ b/src/vs/workbench/api/common/extHostMemento.ts @@ -38,7 +38,9 @@ export class ExtensionMemento implements IExtensionMemento { return this._init; } - get(key: string, defaultValue: T): T { + get(key: string): T | undefined; + get(key: string, defaultValue: T): T; + get(key: string, defaultValue?: T): T { let value = this._value[key]; if (typeof value === 'undefined') { value = defaultValue; @@ -46,11 +48,9 @@ export class ExtensionMemento implements IExtensionMemento { return value; } - update(key: string, value: any): Promise { + update(key: string, value: any): Promise { this._value[key] = value; - return this._storage - .setValue(this._shared, this._id, this._value) - .then(() => true); + return this._storage.setValue(this._shared, this._id, this._value); } dispose(): void { diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 9c2bcd503a574..c8ed21e278d56 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -2319,3 +2319,8 @@ export enum ExtensionExecutionContext { Local = 1, Remote = 2 } + +export enum ExtensionKind { + UI = 1, + Workspace = 2 +} diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 0c1ccf3189042..9898fa25685b2 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -125,10 +125,10 @@ export function createApiFactory( const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(LogOutputChannelFactory, initData.logsLocation, rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); - if (initData.remoteAuthority) { + if (initData.remote.authority) { extHostTask.registerTaskSystem(Schemas.vscodeRemote, { scheme: Schemas.vscodeRemote, - authority: initData.remoteAuthority, + authority: initData.remote.authority, platform: process.platform }); @@ -150,7 +150,7 @@ export function createApiFactory( const extHostLanguages = new ExtHostLanguages(rpcProtocol, extHostDocuments); // Register an output channel for exthost log - const outputChannelName = initData.remoteAuthority ? nls.localize('remote extension host Log', "Remote Extension Host") : nls.localize('extension host Log', "Extension Host"); + const outputChannelName = initData.remote.isRemote ? nls.localize('remote extension host Log', "Remote Extension Host") : nls.localize('extension host Log', "Extension Host"); extHostOutputService.createOutputChannelFromLogFile(outputChannelName, extHostLogService.logFile); // Register API-ish commands @@ -258,12 +258,24 @@ export function createApiFactory( return extHostTerminalService.getDefaultShell(configProvider); }, openExternal(uri: URI) { - return extHostWindow.openUri(uri, { allowTunneling: !!initData.remoteAuthority }); + return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); }, get webviewResourceRoot() { checkProposedApiEnabled(extension); return initData.environment.webviewResourceRoot; }, + get remoteName() { + checkProposedApiEnabled(extension); + if (!initData.remote.authority) { + return undefined; + } + const pos = initData.remote.authority.indexOf('+'); + if (pos < 0) { + // funky? bad authority? + return initData.remote.authority; + } + return initData.remote.authority.substr(0, pos); + } }; if (!initData.environment.extensionTestsLocationURI) { // allow to patch env-function when running tests @@ -824,6 +836,7 @@ export function createApiFactory( EndOfLine: extHostTypes.EndOfLine, EventEmitter: Emitter, ExtensionExecutionContext: extHostTypes.ExtensionExecutionContext, + ExtensionKind: extHostTypes.ExtensionKind, CustomExecution: extHostTypes.CustomExecution, FileChangeType: extHostTypes.FileChangeType, FileSystemError: extHostTypes.FileSystemError, diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 5f4bd8be09527..69d976b10d014 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -32,7 +32,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { VSBuffer } from 'vs/base/common/buffer'; import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; -import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; +import { RemoteAuthorityResolverError, ExtensionExecutionContext, ExtensionKind } from 'vs/workbench/api/common/extHostTypes'; import { IURITransformer } from 'vs/base/common/uriIpc'; interface ITestRunner { @@ -153,7 +153,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { const extensionPaths = await this.getExtensionPathIndex(); NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar), this._environment)); - if (this._initData.remoteAuthority) { + if (this._initData.remote.isRemote) { NodeModuleRequireInterceptor.INSTANCE.register(new OpenNodeModuleFactory( this._extHostContext.getProxy(MainContext.MainThreadWindow), this._extHostContext.getProxy(MainContext.MainThreadTelemetry), @@ -340,7 +340,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { }); } - private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { + private _loadExtensionContext(extensionDescription: IExtensionDescription): Promise { const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage); const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage); @@ -361,7 +361,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { globalStoragePath: this._storagePath.globalValue(extensionDescription), asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), - executionContext: this._initData.remoteAuthority ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local + executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, + extensionKind: this._initData.remote.isRemote ? ExtensionKind.Workspace : ExtensionKind.UI }); }); } @@ -562,7 +563,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // messages to the main process, we delay the exit() by some time setTimeout(() => { // If extension tests are running, give the exit code to the renderer - if (this._initData.remoteAuthority && !!this._initData.environment.extensionTestsLocationURI) { + if (this._initData.remote.isRemote && !!this._initData.environment.extensionTestsLocationURI) { this._mainThreadExtensionsProxy.$onExtensionHostExit(code); return; } diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index f21711a4168d1..5ab1b30e06c75 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -197,6 +197,10 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH id: workspace.id, name: this._labelService.getWorkspaceLabel(workspace) }, + remote: { + isRemote: true, + authority: this._initDataProvider.remoteAuthority + }, resolvedExtensions: resolvedExtensions, hostExtensions: hostExtensions, extensions: remoteExtensionHostData.extensions, @@ -204,7 +208,6 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH logLevel: this._logService.getLevel(), logsLocation: remoteExtensionHostData.extensionHostLogsPath, autoStart: true, - remoteAuthority: this._initDataProvider.remoteAuthority, }; return r; }); diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index efe66b8579cd3..bb552cc31d792 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -403,6 +403,10 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { name: this._labelService.getWorkspaceLabel(workspace), isUntitled: workspace.configuration ? isEqualOrParent(workspace.configuration, this._environmentService.untitledWorkspacesHome) : false }, + remote: { + authority: this._environmentService.configuration.remoteAuthority, + isRemote: false + }, resolvedExtensions: [], hostExtensions: [], extensions: extensionDescriptions, diff --git a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts index d7b8965f8acc0..1a5822e645fb4 100644 --- a/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts +++ b/src/vs/workbench/services/extensions/node/extensionHostProcessSetup.ts @@ -319,10 +319,10 @@ export async function startExtensionHostProcess(): Promise { // Attempt to load uri transformer let uriTransformer: IURITransformer | null = null; - if (initData.remoteAuthority && args.uriTransformerPath) { + if (initData.remote.authority && args.uriTransformerPath) { try { const rawURITransformerFactory = require.__$__nodeRequire(args.uriTransformerPath); - const rawURITransformer = rawURITransformerFactory(initData.remoteAuthority); + const rawURITransformer = rawURITransformerFactory(initData.remote.authority); uriTransformer = new URITransformer(rawURITransformer); } catch (e) { console.error(e); From 0bbe1399c7edac6d8d2db38f38490408ffa22d35 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 12:36:24 +0200 Subject: [PATCH 166/364] debt - use file service based configuration file service --- src/vs/workbench/electron-browser/main.ts | 5 +- .../configuration/browser/configuration.ts | 44 +---------- .../configuration/common/configuration.ts | 7 +- .../node/configurationFileService.ts | 79 ------------------- .../configurationEditingService.test.ts | 11 ++- .../configurationService.test.ts | 22 ++---- 6 files changed, 18 insertions(+), 150 deletions(-) delete mode 100644 src/vs/workbench/services/configuration/node/configurationFileService.ts diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 0ef9f9078d204..0bd39209ff8e9 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -47,10 +47,10 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteExtensionsFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel'; import { DefaultConfigurationExportHelper } from 'vs/workbench/services/configuration/node/configurationExportHelper'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/node/configurationFileService'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { ConfigurationFileService } from '../services/configuration/common/configuration'; class CodeRendererMain extends Disposable { @@ -306,8 +306,7 @@ class CodeRendererMain extends Disposable { } private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + const configurationFileService = new ConfigurationFileService(fileService); const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 0233193437593..8b6b5f292a5c4 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -20,7 +20,7 @@ import { ConfigurationScope } from 'vs/platform/configuration/common/configurati import { extname, join } from 'vs/base/common/path'; import { equals } from 'vs/base/common/objects'; import { Schemas } from 'vs/base/common/network'; -import { IConfigurationModel, compare } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { hash } from 'vs/base/common/hash'; @@ -138,11 +138,7 @@ export class UserConfiguration extends Disposable { async initialize(): Promise { const exists = await this.configurationFileService.exists(this.configurationResource); this.onResourceExists(exists); - const configuraitonModel = await this.reload(); - if (!this.configurationFileService.isWatching) { - this.configurationFileService.whenWatchingStarted.then(() => this.onWatchStarted(configuraitonModel)); - } - return configuraitonModel; + return this.reload(); } async reload(): Promise { @@ -160,14 +156,6 @@ export class UserConfiguration extends Disposable { return this.parser.configurationModel; } - private async onWatchStarted(currentModel: ConfigurationModel): Promise { - const configuraitonModel = await this.reload(); - const { added, removed, updated } = compare(currentModel, configuraitonModel); - if (added.length || removed.length || updated.length) { - this._onDidChangeConfiguration.fire(configuraitonModel); - } - } - private async handleFileEvents(event: FileChangesEvent): Promise { const events = event.changes; @@ -378,10 +366,6 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e))); this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50)); this.workspaceConfigWatcher = this._register(this.watchWorkspaceConfigurationFile()); - - if (!this.configurationFileService.isWatching) { - this.configurationFileService.whenWatchingStarted.then(() => this.onWatchStarted()); - } } get workspaceIdentifier(): IWorkspaceIdentifier | null { @@ -426,18 +410,6 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork return this.getWorkspaceSettings(); } - private async onWatchStarted(): Promise { - if (this.workspaceIdentifier) { - const currentModel = this.getConfigurationModel(); - await this.load(this.workspaceIdentifier); - const newModel = this.getConfigurationModel(); - const { added, removed, updated } = compare(currentModel, newModel); - if (added.length || removed.length || updated.length) { - this._onDidChange.fire(); - } - } - } - private consolidate(): void { this.workspaceSettings = this.workspaceConfigurationModelParser.settingsModel.merge(this.workspaceConfigurationModelParser.launchModel); } @@ -557,9 +529,6 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC this.changeEventTriggerScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50)); this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e))); - if (!this.configurationFileService.isWatching) { - this.configurationFileService.whenWatchingStarted.then(() => this.onWatchStarted()); - } } async loadConfiguration(): Promise { @@ -611,15 +580,6 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC this._cache = this._folderSettingsModelParser.configurationModel.merge(...this._standAloneConfigurations); } - private async onWatchStarted(): Promise { - const currentModel = this._cache; - const newModel = await this.loadConfiguration(); - const { added, removed, updated } = compare(currentModel, newModel); - if (added.length || removed.length || updated.length) { - this._onDidChange.fire(); - } - } - private handleWorkspaceFileEvents(event: FileChangesEvent): void { const events = event.changes; let affectedByChanges = false; diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index a1185aa3001a4..ef661f92a1b98 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -43,10 +43,7 @@ export interface IConfigurationCache { } export interface IConfigurationFileService { - fileService: IFileService | null; readonly onFileChanges: Event; - readonly isWatching: boolean; - readonly whenWatchingStarted: Promise; whenProviderRegistered(scheme: string): Promise; watch(resource: URI): IDisposable; exists(resource: URI): Promise; @@ -55,11 +52,9 @@ export interface IConfigurationFileService { export class ConfigurationFileService implements IConfigurationFileService { - constructor(public fileService: IFileService) { } + constructor(private readonly fileService: IFileService) { } get onFileChanges() { return this.fileService.onFileChanges; } - readonly whenWatchingStarted: Promise = Promise.resolve(); - readonly isWatching: boolean = true; whenProviderRegistered(scheme: string): Promise { if (this.fileService.canHandleResource(URI.from({ scheme }))) { diff --git a/src/vs/workbench/services/configuration/node/configurationFileService.ts b/src/vs/workbench/services/configuration/node/configurationFileService.ts deleted file mode 100644 index 18690c4404066..0000000000000 --- a/src/vs/workbench/services/configuration/node/configurationFileService.ts +++ /dev/null @@ -1,79 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as pfs from 'vs/base/node/pfs'; -import { IConfigurationFileService, ConfigurationFileService as FileServiceBasedConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; -import { URI } from 'vs/base/common/uri'; -import { Event, Emitter } from 'vs/base/common/event'; -import { FileChangesEvent, IFileService } from 'vs/platform/files/common/files'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { Schemas } from 'vs/base/common/network'; - -export class ConfigurationFileService extends Disposable implements IConfigurationFileService { - - private _fileServiceBasedConfigurationFileService: FileServiceBasedConfigurationFileService | null = null; - private _fileServiceBasedConfigurationFileServiceCallback: (fileServiceBasedConfigurationFileService: FileServiceBasedConfigurationFileService) => void; - private _whenFileServiceBasedConfigurationFileServiceAvailable: Promise = new Promise((c) => this._fileServiceBasedConfigurationFileServiceCallback = c); - private _watchResources: { resource: URI, disposable: { disposable: IDisposable | null } }[] = []; - readonly whenWatchingStarted: Promise = this._whenFileServiceBasedConfigurationFileServiceAvailable.then(() => undefined); - - private readonly _onFileChanges: Emitter = this._register(new Emitter()); - readonly onFileChanges: Event = this._onFileChanges.event; - - get isWatching(): boolean { - return this._fileServiceBasedConfigurationFileService ? this._fileServiceBasedConfigurationFileService.isWatching : false; - } - - watch(resource: URI): IDisposable { - if (this._fileServiceBasedConfigurationFileService) { - return this._fileServiceBasedConfigurationFileService.watch(resource); - } - const disposable: { disposable: IDisposable | null } = { disposable: null }; - this._watchResources.push({ resource, disposable }); - return toDisposable(() => { - if (disposable.disposable) { - disposable.disposable.dispose(); - } - }); - } - - whenProviderRegistered(scheme: string): Promise { - if (scheme === Schemas.file) { - return Promise.resolve(); - } - return this._whenFileServiceBasedConfigurationFileServiceAvailable - .then(fileServiceBasedConfigurationFileService => fileServiceBasedConfigurationFileService.whenProviderRegistered(scheme)); - } - - exists(resource: URI): Promise { - return this._fileServiceBasedConfigurationFileService ? this._fileServiceBasedConfigurationFileService.exists(resource) : pfs.exists(resource.fsPath); - } - - async readFile(resource: URI): Promise { - if (this._fileServiceBasedConfigurationFileService) { - return this._fileServiceBasedConfigurationFileService.readFile(resource); - } else { - const contents = await pfs.readFile(resource.fsPath); - return contents.toString(); - } - } - - private _fileService: IFileService | null; - get fileService(): IFileService | null { - return this._fileService; - } - - set fileService(fileService: IFileService | null) { - if (fileService && !this._fileServiceBasedConfigurationFileService) { - this._fileServiceBasedConfigurationFileService = new FileServiceBasedConfigurationFileService(fileService); - this._fileService = fileService; - this._register(this._fileServiceBasedConfigurationFileService.onFileChanges(e => this._onFileChanges.fire(e))); - for (const { resource, disposable } of this._watchResources) { - disposable.disposable = this._fileServiceBasedConfigurationFileService.watch(resource); - } - this._fileServiceBasedConfigurationFileServiceCallback(this._fileServiceBasedConfigurationFileService); - } - } -} diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index 6634fcb6e04b4..1e8bf7dc6fa04 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -19,7 +19,7 @@ import * as uuid from 'vs/base/common/uuid'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService'; import { ConfigurationEditingService, ConfigurationEditingError, ConfigurationEditingErrorCode, EditableConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditingService'; -import { WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration'; +import { WORKSPACE_STANDALONE_CONFIGURATIONS, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; @@ -39,7 +39,6 @@ import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; import { IFileService } from 'vs/platform/files/common/files'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/node/configurationFileService'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -104,14 +103,14 @@ suite('ConfigurationEditingService', () => { const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); instantiationService.stub(IEnvironmentService, environmentService); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); + const fileService = new FileService(new NullLogService()); + fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); + instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(), remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(fileService), remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? { id: '' } : { folder: URI.file(workspaceDir), id: createHash('md5').update(URI.file(workspaceDir).toString()).digest('hex') }).then(() => { instantiationService.stub(IConfigurationService, workspaceService); - const fileService = new FileService(new NullLogService()); - fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - instantiationService.stub(IFileService, fileService); instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService)); instantiationService.stub(ITextModelService, instantiationService.createInstance(TextModelResolverService)); instantiationService.stub(ICommandService, CommandService); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index 3fd5bf00d75a8..8e6383fcff418 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -41,9 +41,8 @@ import { FileService } from 'vs/workbench/services/files/common/fileService'; import { NullLogService } from 'vs/platform/log/common/log'; import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/node/configurationFileService'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; +import { IConfigurationCache, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { VSBuffer } from 'vs/base/common/buffer'; import { SignService } from 'vs/platform/sign/browser/signService'; @@ -104,7 +103,7 @@ suite('WorkspaceContextService - Folder', () => { workspaceResource = folderDir; const globalSettingsFile = path.join(parentDir, 'settings.json'); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); + workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(new FileService(new NullLogService())), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); return (workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); }); }); @@ -166,7 +165,7 @@ suite('WorkspaceContextService - Workspace', () => { const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(), remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(new FileService(new NullLogService())), remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -224,8 +223,7 @@ suite('WorkspaceContextService - Workspace Editing', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + const configurationFileService = new ConfigurationFileService(fileService); const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -485,8 +483,7 @@ suite('WorkspaceService - Initialization', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + const configurationFileService = new ConfigurationFileService(fileService); const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -749,8 +746,7 @@ suite('WorkspaceConfigurationService - Folder', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + const configurationFileService = new ConfigurationFileService(fileService); const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -1077,8 +1073,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + const configurationFileService = new ConfigurationFileService(fileService); const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -1479,8 +1474,7 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - const configurationFileService = new ConfigurationFileService(); - configurationFileService.fileService = fileService; + const configurationFileService = new ConfigurationFileService(fileService); const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve() }; testObject = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache, remoteAuthority }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, testObject); From 24e05597feb6f07c98a526d961705c6bc235b2fc Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 12:39:59 +0200 Subject: [PATCH 167/364] fix tests --- .../test/electron-browser/configurationService.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index 8e6383fcff418..36767ce3242a1 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -165,7 +165,9 @@ suite('WorkspaceContextService - Workspace', () => { const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, path.join(parentDir, 'settings.json')); const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {}); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(new FileService(new NullLogService())), remoteAgentService); + const fileService = new FileService(new NullLogService()); + fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(fileService), remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); From 27ef2915f25270ef03be88117937c047d778051c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 12:58:42 +0200 Subject: [PATCH 168/364] debt create configuration file service inside configuration service --- src/vs/workbench/browser/web.main.ts | 3 +-- src/vs/workbench/electron-browser/main.ts | 5 +---- .../configuration/browser/configuration.ts | 18 +++++++++--------- .../browser/configurationService.ts | 13 ++++++++----- .../configuration/common/configuration.ts | 14 +++----------- .../configurationEditingService.test.ts | 4 ++-- .../configurationService.test.ts | 16 ++++++++-------- 7 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 6f1954ba2520a..1986fb66422c9 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -29,7 +29,6 @@ import { URI } from 'vs/base/common/uri'; import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces'; import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService'; import { ConfigurationCache } from 'vs/workbench/services/configuration/browser/configurationCache'; -import { ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { WebResources } from 'vs/workbench/browser/web.resources'; import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/browser/signService'; @@ -137,7 +136,7 @@ class CodeRendererMain extends Disposable { } private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, new ConfigurationFileService(fileService), remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, fileService, remoteAgentService); try { await workspaceService.initialize(payload); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 0bd39209ff8e9..87259d771c9da 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -50,7 +50,6 @@ import { ConfigurationCache } from 'vs/workbench/services/configuration/node/con import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; -import { ConfigurationFileService } from '../services/configuration/common/configuration'; class CodeRendererMain extends Disposable { @@ -306,9 +305,7 @@ class CodeRendererMain extends Disposable { } private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const configurationFileService = new ConfigurationFileService(fileService); - - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); try { await workspaceService.initialize(payload); diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 8b6b5f292a5c4..a2f7603280985 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -12,7 +12,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, IConfigurationFileService, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -27,7 +27,7 @@ import { hash } from 'vs/base/common/hash'; export class RemoteUserConfiguration extends Disposable { private readonly _cachedConfiguration: CachedUserConfiguration; - private readonly _configurationFileService: IConfigurationFileService; + private readonly _configurationFileService: ConfigurationFileService; private _userConfiguration: UserConfiguration | CachedUserConfiguration; private _userConfigurationInitializationPromise: Promise | null = null; @@ -37,7 +37,7 @@ export class RemoteUserConfiguration extends Disposable { constructor( remoteAuthority: string, configurationCache: IConfigurationCache, - configurationFileService: IConfigurationFileService, + configurationFileService: ConfigurationFileService, remoteAgentService: IRemoteAgentService ) { super(); @@ -103,7 +103,7 @@ export class UserConfiguration extends Disposable { constructor( private readonly configurationResource: URI, private readonly scopes: ConfigurationScope[] | undefined, - private readonly configurationFileService: IConfigurationFileService + private readonly configurationFileService: ConfigurationFileService ) { super(); @@ -240,7 +240,7 @@ class CachedUserConfiguration extends Disposable { export class WorkspaceConfiguration extends Disposable { - private readonly _configurationFileService: IConfigurationFileService; + private readonly _configurationFileService: ConfigurationFileService; private readonly _cachedConfiguration: CachedWorkspaceConfiguration; private _workspaceConfiguration: IWorkspaceConfiguration; private _workspaceConfigurationChangeDisposable: IDisposable = Disposable.None; @@ -254,7 +254,7 @@ export class WorkspaceConfiguration extends Disposable { constructor( configurationCache: IConfigurationCache, - configurationFileService: IConfigurationFileService + configurationFileService: ConfigurationFileService ) { super(); this._configurationFileService = configurationFileService; @@ -357,7 +357,7 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork protected readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; - constructor(private configurationFileService: IConfigurationFileService) { + constructor(private configurationFileService: ConfigurationFileService) { super(); this.workspaceConfigurationModelParser = new WorkspaceConfigurationModelParser(''); @@ -518,7 +518,7 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC protected readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; - constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private configurationFileService: IConfigurationFileService) { + constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private configurationFileService: ConfigurationFileService) { super(); this.configurationNames = [FOLDER_SETTINGS_NAME /*First one should be settings */, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY]; @@ -685,7 +685,7 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat readonly workspaceFolder: IWorkspaceFolder, configFolderRelativePath: string, private readonly workbenchState: WorkbenchState, - configurationFileService: IConfigurationFileService, + configurationFileService: ConfigurationFileService, configurationCache: IConfigurationCache ) { super(); diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index f0c0dfe003143..a8e14a6bcd399 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -15,7 +15,7 @@ import { isLinux } from 'vs/base/common/platform'; import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels'; import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, IConfigurationFileService, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { Registry } from 'vs/platform/registry/common/platform'; import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry'; import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces'; @@ -28,6 +28,7 @@ import { localize } from 'vs/nls'; import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { IFileService } from 'vs/platform/files/common/files'; export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { @@ -43,9 +44,10 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private remoteUserConfiguration: RemoteUserConfiguration | null = null; private workspaceConfiguration: WorkspaceConfiguration; private cachedFolderConfigs: ResourceMap; - private workspaceEditingQueue: Queue; + private readonly configurationFileService: ConfigurationFileService; + protected readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); public readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; @@ -66,7 +68,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic constructor( { userSettingsResource, remoteAuthority, configurationCache }: { userSettingsResource?: URI, remoteAuthority?: string, configurationCache: IConfigurationCache }, - private readonly configurationFileService: IConfigurationFileService, + fileService: IFileService, remoteAgentService: IRemoteAgentService, ) { super(); @@ -74,14 +76,15 @@ export class WorkspaceService extends Disposable implements IConfigurationServic this.completeWorkspaceBarrier = new Barrier(); this.defaultConfiguration = new DefaultConfigurationModel(); this.configurationCache = configurationCache; + this.configurationFileService = new ConfigurationFileService(fileService); this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), this.workspace); this.cachedFolderConfigs = new ResourceMap(); if (userSettingsResource) { - this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, configurationFileService)); + this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, this.configurationFileService)); this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); } if (remoteAuthority) { - this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, configurationFileService, remoteAgentService)); + this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService)); this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration))); } this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, this.configurationFileService)); diff --git a/src/vs/workbench/services/configuration/common/configuration.ts b/src/vs/workbench/services/configuration/common/configuration.ts index ef661f92a1b98..2910b6feccc6e 100644 --- a/src/vs/workbench/services/configuration/common/configuration.ts +++ b/src/vs/workbench/services/configuration/common/configuration.ts @@ -5,10 +5,10 @@ import { URI } from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; -import { Event } from 'vs/base/common/event'; -import { FileChangesEvent, IFileService } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; +export const USER_CONFIGURATION_KEY = 'settings.json'; export const FOLDER_CONFIG_FOLDER_NAME = '.vscode'; export const FOLDER_SETTINGS_NAME = 'settings'; export const FOLDER_SETTINGS_PATH = `${FOLDER_CONFIG_FOLDER_NAME}/${FOLDER_SETTINGS_NAME}.json`; @@ -42,15 +42,7 @@ export interface IConfigurationCache { } -export interface IConfigurationFileService { - readonly onFileChanges: Event; - whenProviderRegistered(scheme: string): Promise; - watch(resource: URI): IDisposable; - exists(resource: URI): Promise; - readFile(resource: URI): Promise; -} - -export class ConfigurationFileService implements IConfigurationFileService { +export class ConfigurationFileService { constructor(private readonly fileService: IFileService) { } diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index 1e8bf7dc6fa04..64b5b994371ad 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -19,7 +19,7 @@ import * as uuid from 'vs/base/common/uuid'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService'; import { ConfigurationEditingService, ConfigurationEditingError, ConfigurationEditingErrorCode, EditableConfigurationTarget } from 'vs/workbench/services/configuration/common/configurationEditingService'; -import { WORKSPACE_STANDALONE_CONFIGURATIONS, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; +import { WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; @@ -107,7 +107,7 @@ suite('ConfigurationEditingService', () => { fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(fileService), remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? { id: '' } : { folder: URI.file(workspaceDir), id: createHash('md5').update(URI.file(workspaceDir).toString()).digest('hex') }).then(() => { instantiationService.stub(IConfigurationService, workspaceService); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index 36767ce3242a1..cbd400263ee98 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -42,7 +42,7 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IConfigurationCache, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; +import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; import { VSBuffer } from 'vs/base/common/buffer'; import { SignService } from 'vs/platform/sign/browser/signService'; @@ -103,7 +103,7 @@ suite('WorkspaceContextService - Folder', () => { workspaceResource = folderDir; const globalSettingsFile = path.join(parentDir, 'settings.json'); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(new FileService(new NullLogService())), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); + workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new FileService(new NullLogService()), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); return (workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); }); }); @@ -167,7 +167,7 @@ suite('WorkspaceContextService - Workspace', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new ConfigurationFileService(fileService), remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -225,7 +225,7 @@ suite('WorkspaceContextService - Workspace Editing', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(fileService); + const configurationFileService = fileService; const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -485,7 +485,7 @@ suite('WorkspaceService - Initialization', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(fileService); + const configurationFileService = fileService; const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -748,7 +748,7 @@ suite('WorkspaceConfigurationService - Folder', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(fileService); + const configurationFileService = fileService; const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -1075,7 +1075,7 @@ suite('WorkspaceConfigurationService-Multiroot', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = new ConfigurationFileService(fileService); + const configurationFileService = fileService; const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); @@ -1476,7 +1476,7 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - const configurationFileService = new ConfigurationFileService(fileService); + const configurationFileService = fileService; const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve() }; testObject = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache, remoteAuthority }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, testObject); From 0c890df52204b829d460050bb18103791086fdab Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 14:37:29 +0200 Subject: [PATCH 169/364] First cut of file service based user data service --- .../userData/common/fileUserDataService.ts | 83 +++++++++++++++++++ .../userData/common/userDataService.ts | 7 +- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 src/vs/workbench/services/userData/common/fileUserDataService.ts diff --git a/src/vs/workbench/services/userData/common/fileUserDataService.ts b/src/vs/workbench/services/userData/common/fileUserDataService.ts new file mode 100644 index 0000000000000..e0690f41ea8a0 --- /dev/null +++ b/src/vs/workbench/services/userData/common/fileUserDataService.ts @@ -0,0 +1,83 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event, Emitter } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IUserDataService, IUserDataChangesEvent } from './userDataService'; +import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files'; +import { URI } from 'vs/base/common/uri'; +import * as resources from 'vs/base/common/resources'; +import { TernarySearchTree } from 'vs/base/common/map'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; + +export class FileUserDataService extends Disposable implements IUserDataService { + _serviceBrand: any; + + private readonly settingsHome: URI; + + private _onDidChange: Emitter = this._register(new Emitter()); + readonly onDidChange: Event = this._onDidChange.event; + + constructor( + @IEnvironmentService environmentService: IEnvironmentService, + @IFileService private readonly fileService: IFileService + ) { + super(); + // Assumption: This path always exists + this.settingsHome = environmentService.appSettingsHome; + this.fileService.watch(this.settingsHome); + + this._register(this.fileService.onFileChanges(e => this.handleFileChanges(e))); + } + + private handleFileChanges(event: FileChangesEvent): void { + const changedKeys: string[] = []; + for (const change of event.changes) { + const key = resources.relativePath(this.settingsHome, change.resource); + if (key) { + changedKeys.push(key); + } + } + if (changedKeys.length) { + this._onDidChange.fire(new UserDataChangesEvent(changedKeys)); + } + } + + read(key: string): Promise { + return this.fileService.readFile(this.toResource(key)).then(content => content.value.toString()); + } + + write(key: string, value: string): Promise { + return this.fileService.writeFile(this.toResource(key), VSBuffer.fromString(value)).then(() => undefined); + } + + private toResource(key: string): URI { + return resources.joinPath(this.settingsHome, ...key.split('/')); + } + +} + +class UserDataChangesEvent implements IUserDataChangesEvent { + + private _keysTree: TernarySearchTree | undefined = undefined; + + constructor(readonly keys: string[]) { } + + private get keysTree(): TernarySearchTree { + if (!this._keysTree) { + this._keysTree = TernarySearchTree.forPaths(); + for (const key of this.keys) { + this._keysTree.set(key, key); + } + } + return this._keysTree; + } + + contains(keyOrSegment: string): boolean { + return this.keysTree.findSubstr(keyOrSegment) !== undefined; + } + +} \ No newline at end of file diff --git a/src/vs/workbench/services/userData/common/userDataService.ts b/src/vs/workbench/services/userData/common/userDataService.ts index 64fb82202a3dc..81c8b5dfd76db 100644 --- a/src/vs/workbench/services/userData/common/userDataService.ts +++ b/src/vs/workbench/services/userData/common/userDataService.ts @@ -8,10 +8,15 @@ import { Event } from 'vs/base/common/event'; export const IUserDataService = createDecorator('userDataService'); +export interface IUserDataChangesEvent { + keys: string[]; + contains(keyOrSegment: string): boolean; +} + export interface IUserDataService { _serviceBrand: any; - onDidChange: Event; + onDidChange: Event; read(key: string): Promise; From 0779716aae9d4b4fc93725a6c1f1fe9efc00ade1 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 14:39:04 +0200 Subject: [PATCH 170/364] Use user data service for reading settings --- src/vs/workbench/browser/web.main.ts | 12 +++- src/vs/workbench/electron-browser/main.ts | 12 +++- .../configuration/browser/configuration.ts | 55 ++++++++++++++++--- .../browser/configurationService.ts | 18 +++--- .../configurationEditingService.test.ts | 4 +- .../configurationService.test.ts | 35 +++++++----- 6 files changed, 97 insertions(+), 39 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 1986fb66422c9..9b4051ac41087 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -35,6 +35,8 @@ import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; import { ProductService } from 'vs/platform/product/browser/productService'; +import { FileUserDataService } from '../services/userData/common/fileUserDataService'; +import { IUserDataService } from '../services/userData/common/userDataService'; class CodeRendererMain extends Disposable { @@ -117,10 +119,14 @@ class CodeRendererMain extends Disposable { fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); } + // User Data Service + const userDataService = this._register(new FileUserDataService(environmentService, fileService)); + serviceCollection.set(IUserDataService, userDataService); + const payload = await this.resolveWorkspaceInitializationPayload(); await Promise.all([ - this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { + this.createWorkspaceService(payload, environmentService, fileService, userDataService, remoteAgentService, logService).then(service => { // Workspace serviceCollection.set(IWorkspaceContextService, service); @@ -135,8 +141,8 @@ class CodeRendererMain extends Disposable { return { serviceCollection, logService }; } - private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, fileService, remoteAgentService); + private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, userDataService: IUserDataService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { + const workspaceService = new WorkspaceService({ remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, fileService, userDataService, remoteAgentService); try { await workspaceService.initialize(payload); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 87259d771c9da..2d11615deb99e 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -50,6 +50,8 @@ import { ConfigurationCache } from 'vs/workbench/services/configuration/node/con import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { IUserDataService } from '../services/userData/common/userDataService'; +import { FileUserDataService } from '../services/userData/common/fileUserDataService'; class CodeRendererMain extends Disposable { @@ -205,10 +207,14 @@ class CodeRendererMain extends Disposable { fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); } + // User Data Service + const userDataService = this._register(new FileUserDataService(environmentService, fileService)); + serviceCollection.set(IUserDataService, userDataService); + const payload = await this.resolveWorkspaceInitializationPayload(environmentService); const services = await Promise.all([ - this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { + this.createWorkspaceService(payload, environmentService, fileService, userDataService, remoteAgentService, logService).then(service => { // Workspace serviceCollection.set(IWorkspaceContextService, service); @@ -304,8 +310,8 @@ class CodeRendererMain extends Disposable { return; } - private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); + private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, userDataService: IUserDataService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { + const workspaceService = new WorkspaceService({ remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); try { await workspaceService.initialize(payload); diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index a2f7603280985..8d4f4245f5db5 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -12,7 +12,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, USER_CONFIGURATION_KEY, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -23,12 +23,51 @@ import { Schemas } from 'vs/base/common/network'; import { IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { hash } from 'vs/base/common/hash'; +import { IUserDataService } from '../../userData/common/userDataService'; + +export class UserConfiguration extends Disposable { + + private readonly parser: ConfigurationModelParser; + private readonly reloadConfigurationScheduler: RunOnceScheduler; + protected readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); + readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; + + constructor( + private readonly scopes: ConfigurationScope[] | undefined, + private readonly userDataService: IUserDataService + ) { + super(); + + this.parser = new ConfigurationModelParser(USER_CONFIGURATION_KEY, this.scopes); + this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50)); + this._register(Event.filter(this.userDataService.onDidChange, e => e.contains(USER_CONFIGURATION_KEY))(() => this.reloadConfigurationScheduler.schedule())); + } + + async initialize(): Promise { + return this.reload(); + } + + async reload(): Promise { + try { + const content = await this.userDataService.read(USER_CONFIGURATION_KEY); + this.parser.parseContent(content); + return this.parser.configurationModel; + } catch (e) { + return new ConfigurationModel(); + } + } + + reprocess(): ConfigurationModel { + this.parser.parse(); + return this.parser.configurationModel; + } +} export class RemoteUserConfiguration extends Disposable { - private readonly _cachedConfiguration: CachedUserConfiguration; + private readonly _cachedConfiguration: CachedRemoteUserConfiguration; private readonly _configurationFileService: ConfigurationFileService; - private _userConfiguration: UserConfiguration | CachedUserConfiguration; + private _userConfiguration: FileServiceBasedRemoteUserConfiguration | CachedRemoteUserConfiguration; private _userConfigurationInitializationPromise: Promise | null = null; private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); @@ -42,10 +81,10 @@ export class RemoteUserConfiguration extends Disposable { ) { super(); this._configurationFileService = configurationFileService; - this._userConfiguration = this._cachedConfiguration = new CachedUserConfiguration(remoteAuthority, configurationCache); + this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache); remoteAgentService.getEnvironment().then(async environment => { if (environment) { - const userConfiguration = this._register(new UserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService)); + const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService)); this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel))); this._userConfigurationInitializationPromise = userConfiguration.initialize(); const configurationModel = await this._userConfigurationInitializationPromise; @@ -57,7 +96,7 @@ export class RemoteUserConfiguration extends Disposable { } async initialize(): Promise { - if (this._userConfiguration instanceof UserConfiguration) { + if (this._userConfiguration instanceof FileServiceBasedRemoteUserConfiguration) { return this._userConfiguration.initialize(); } @@ -90,7 +129,7 @@ export class RemoteUserConfiguration extends Disposable { } } -export class UserConfiguration extends Disposable { +class FileServiceBasedRemoteUserConfiguration extends Disposable { private readonly parser: ConfigurationModelParser; private readonly reloadConfigurationScheduler: RunOnceScheduler; @@ -190,7 +229,7 @@ export class UserConfiguration extends Disposable { } } -class CachedUserConfiguration extends Disposable { +class CachedRemoteUserConfiguration extends Disposable { private readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index a8e14a6bcd399..e98c108ea0638 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -29,6 +29,7 @@ import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IFileService } from 'vs/platform/files/common/files'; +import { IUserDataService } from '../../userData/common/userDataService'; export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { @@ -40,7 +41,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private _configuration: Configuration; private initialized: boolean = false; private defaultConfiguration: DefaultConfigurationModel; - private localUserConfiguration: UserConfiguration | null = null; + private localUserConfiguration: UserConfiguration; private remoteUserConfiguration: RemoteUserConfiguration | null = null; private workspaceConfiguration: WorkspaceConfiguration; private cachedFolderConfigs: ResourceMap; @@ -67,9 +68,10 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private cyclicDependency = new Promise(resolve => this.cyclicDependencyReady = resolve); constructor( - { userSettingsResource, remoteAuthority, configurationCache }: { userSettingsResource?: URI, remoteAuthority?: string, configurationCache: IConfigurationCache }, + { remoteAuthority, configurationCache }: { remoteAuthority?: string, configurationCache: IConfigurationCache }, fileService: IFileService, - remoteAgentService: IRemoteAgentService, + userDataService: IUserDataService, + remoteAgentService: IRemoteAgentService ) { super(); @@ -79,10 +81,8 @@ export class WorkspaceService extends Disposable implements IConfigurationServic this.configurationFileService = new ConfigurationFileService(fileService); this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), this.workspace); this.cachedFolderConfigs = new ResourceMap(); - if (userSettingsResource) { - this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, this.configurationFileService)); - this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); - } + this.localUserConfiguration = this._register(new UserConfiguration(remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, userDataService)); + this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); if (remoteAuthority) { this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService)); this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration))); @@ -426,7 +426,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private initializeUserConfiguration(): Promise<{ local: ConfigurationModel, remote: ConfigurationModel }> { - return Promise.all([this.localUserConfiguration ? this.localUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel()), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]) + return Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]) .then(([local, remote]) => ({ local, remote })); } @@ -435,7 +435,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } private reloadLocalUserConfiguration(key?: string): Promise { - return this.localUserConfiguration ? this.localUserConfiguration.reload() : Promise.resolve(new ConfigurationModel()); + return this.localUserConfiguration.reload(); } private reloadRemoeUserConfiguration(key?: string): Promise { diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index 64b5b994371ad..f94f09794b480 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -39,6 +39,7 @@ import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; import { IFileService } from 'vs/platform/files/common/files'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; +import { FileUserDataService } from 'vs/workbench/services/userData/common/fileUserDataService'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -107,7 +108,8 @@ suite('ConfigurationEditingService', () => { fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? { id: '' } : { folder: URI.file(workspaceDir), id: createHash('md5').update(URI.file(workspaceDir).toString()).digest('hex') }).then(() => { instantiationService.stub(IConfigurationService, workspaceService); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index cbd400263ee98..3e1e4be3e3c7e 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -31,7 +31,7 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/ import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { createHash } from 'crypto'; import { Schemas } from 'vs/base/common/network'; -import { originalFSPath } from 'vs/base/common/resources'; +import { originalFSPath, dirname } from 'vs/base/common/resources'; import { isLinux } from 'vs/base/common/platform'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; @@ -45,14 +45,16 @@ import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEn import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; import { VSBuffer } from 'vs/base/common/buffer'; import { SignService } from 'vs/platform/sign/browser/signService'; +import { FileUserDataService } from 'vs/workbench/services/userData/common/fileUserDataService'; class SettingsTestEnvironmentService extends EnvironmentService { - constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome: string) { + constructor(args: ParsedArgs, _execPath: string, private _settingsPath: string) { super(args, _execPath); } - get settingsResource(): URI { return URI.file(this.customAppSettingsHome); } + get appSettingsHome(): URI { return dirname(this.settingsResource); } + get settingsResource(): URI { return URI.file(this._settingsPath); } } function setUpFolderWorkspace(folderName: string): Promise<{ parentDir: string, folderDir: string }> { @@ -103,7 +105,9 @@ suite('WorkspaceContextService - Folder', () => { workspaceResource = folderDir; const globalSettingsFile = path.join(parentDir, 'settings.json'); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new FileService(new NullLogService()), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); + const fileService = new FileService(new NullLogService()); + const userDataService = new FileUserDataService(environmentService, fileService); + workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); return (workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); }); }); @@ -167,7 +171,8 @@ suite('WorkspaceContextService - Workspace', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -225,8 +230,8 @@ suite('WorkspaceContextService - Workspace Editing', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -485,8 +490,8 @@ suite('WorkspaceService - Initialization', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -748,8 +753,8 @@ suite('WorkspaceConfigurationService - Folder', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -1075,8 +1080,8 @@ suite('WorkspaceConfigurationService-Multiroot', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const configurationFileService = fileService; - const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -1476,9 +1481,9 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - const configurationFileService = fileService; const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve() }; - testObject = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache, remoteAuthority }, configurationFileService, remoteAgentService); + const userDataService = new FileUserDataService(environmentService, fileService); + testObject = new WorkspaceService({ configurationCache, remoteAuthority }, fileService, userDataService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); instantiationService.stub(IEnvironmentService, environmentService); From fb56f999750231d93e8e8a14eb4fbb85519919c8 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 20 Jun 2019 15:17:30 +0200 Subject: [PATCH 171/364] Update distro hash --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f473c58396d3..51b6853bd9665 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "336a0c632c464d9c81e6fbff00154852967eaf02", + "distro": "98c55ad448ca078f4eb07091bf54b4cbc189203a", "author": { "name": "Microsoft Corporation" }, From 997e91421e9490a11ff3b69dd285b2c175efbe46 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 15:47:46 +0200 Subject: [PATCH 172/364] add diagnostic tool for git file event issues --- extensions/git/src/model.ts | 2 +- extensions/git/src/repository.ts | 64 +++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index 2c9085b6820cb..a04dc33c8beb8 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -233,7 +233,7 @@ export class Model { } const dotGit = await this.git.getRepositoryDotGit(repositoryRoot); - const repository = new Repository(this.git.open(repositoryRoot, dotGit), this.globalState); + const repository = new Repository(this.git.open(repositoryRoot, dotGit), this.globalState, this.outputChannel); this.open(repository); } catch (err) { diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index a6ac57bc6918c..5cbe55e8a2192 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -3,9 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType } from 'vscode'; +import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env } from 'vscode'; import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git'; -import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, toDisposable } from './util'; +import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, toDisposable, combinedDisposable } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; import { AutoFetcher } from './autofetch'; @@ -447,6 +447,39 @@ class ProgressManager { } } +class FileEventLogger { + + private eventDisposable: IDisposable = EmptyDisposable; + private logLevelDisposable: IDisposable = EmptyDisposable; + + constructor( + private onWorkspaceWorkingTreeFileChange: Event, + private onDotGitFileChange: Event, + private outputChannel: OutputChannel + ) { + this.logLevelDisposable = env.onDidChangeLogLevel(this.onDidChangeLogLevel, this); + this.onDidChangeLogLevel(env.logLevel); + } + + private onDidChangeLogLevel(level: LogLevel): void { + this.eventDisposable.dispose(); + + if (level > LogLevel.Debug) { + return; + } + + this.eventDisposable = combinedDisposable([ + this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannel.appendLine(`[debug] [wt] Change: ${uri.fsPath}`)), + this.onDotGitFileChange(uri => this.outputChannel.appendLine(`[debug] [.git] Change: ${uri.fsPath}`)) + ]); + } + + dispose(): void { + this.eventDisposable.dispose(); + this.logLevelDisposable.dispose(); + } +} + export class Repository implements Disposable { private _onDidChangeRepository = new EventEmitter(); @@ -547,34 +580,39 @@ export class Repository implements Disposable { private isRepositoryHuge = false; private didWarnAboutLimit = false; private isFreshRepository: boolean | undefined = undefined; + + private disposables: Disposable[] = []; constructor( private readonly repository: BaseRepository, - globalState: Memento + globalState: Memento, + outputChannel: OutputChannel ) { const workspaceWatcher = workspace.createFileSystemWatcher('**'); this.disposables.push(workspaceWatcher); - const onWorkspaceFileChanges = anyEvent(workspaceWatcher.onDidChange, workspaceWatcher.onDidCreate, workspaceWatcher.onDidDelete); - const onWorkspaceRepositoryFileChanges = filterEvent(onWorkspaceFileChanges, uri => isDescendant(repository.root, uri.fsPath)); - const onWorkspaceWorkingTreeFileChanges = filterEvent(onWorkspaceRepositoryFileChanges, uri => !/\/\.git($|\/)/.test(uri.path)); + const onWorkspaceFileChange = anyEvent(workspaceWatcher.onDidChange, workspaceWatcher.onDidCreate, workspaceWatcher.onDidDelete); + const onWorkspaceRepositoryFileChange = filterEvent(onWorkspaceFileChange, uri => isDescendant(repository.root, uri.fsPath)); + const onWorkspaceWorkingTreeFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => !/\/\.git($|\/)/.test(uri.path)); const dotGitWatcher = fs.watch(repository.dotGit); - const onRepositoryFileEmitter = new EventEmitter(); - dotGitWatcher.on('change', (_, e) => onRepositoryFileEmitter.fire(Uri.file(path.join(repository.dotGit, e as string)))); + const onDotGitFileChangeEmitter = new EventEmitter(); + dotGitWatcher.on('change', (_, e) => onDotGitFileChangeEmitter.fire(Uri.file(path.join(repository.dotGit, e as string)))); dotGitWatcher.on('error', err => console.error(err)); this.disposables.push(toDisposable(() => dotGitWatcher.close())); - const onRelevantRepositoryChanges = filterEvent(onRepositoryFileEmitter.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)); + const onDotGitFileChange = filterEvent(onDotGitFileChangeEmitter.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)); // FS changes should trigger `git status`: // - any change inside the repository working tree // - any change whithin the first level of the `.git` folder, except the folder itself and `index.lock` - const onFSChange = anyEvent(onWorkspaceWorkingTreeFileChanges, onRelevantRepositoryChanges); - onFSChange(this.onFSChange, this, this.disposables); + const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, onDotGitFileChange); + onFileChange(this.onFileChange, this, this.disposables); // Relevate repository changes should trigger virtual document change events - onRelevantRepositoryChanges(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); + onDotGitFileChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); + + this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, onDotGitFileChange, outputChannel)); const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); @@ -1454,7 +1492,7 @@ export class Repository implements Disposable { return result; } - private onFSChange(_uri: Uri): void { + private onFileChange(_uri: Uri): void { const config = workspace.getConfiguration('git'); const autorefresh = config.get('autorefresh'); From 3839ce7751c2b670c0145161ff7774c4c8884c4e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 20 Jun 2019 15:54:18 +0200 Subject: [PATCH 173/364] :lipstick: --- .../workbench/api/common/extHostFileSystem.ts | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index a46c3fd841787..da723e3d01b97 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -113,7 +113,6 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { private readonly _watches = new Map(); private _linkProviderRegistration: IDisposable; - // Used as a handle both for file system providers and resource label formatters (being lazy) private _handlePool: number = 0; constructor(mainContext: IMainContext, private _extHostLanguageFeatures: ExtHostLanguageFeatures) { @@ -223,31 +222,31 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $stat(handle: number, resource: UriComponents): Promise { - return Promise.resolve(this.getProvider(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat); + return Promise.resolve(this._getFsProvider(handle).stat(URI.revive(resource))).then(ExtHostFileSystem._asIStat); } $readdir(handle: number, resource: UriComponents): Promise<[string, files.FileType][]> { - return Promise.resolve(this.getProvider(handle).readDirectory(URI.revive(resource))); + return Promise.resolve(this._getFsProvider(handle).readDirectory(URI.revive(resource))); } $readFile(handle: number, resource: UriComponents): Promise { - return Promise.resolve(this.getProvider(handle).readFile(URI.revive(resource))).then(data => VSBuffer.wrap(data)); + return Promise.resolve(this._getFsProvider(handle).readFile(URI.revive(resource))).then(data => VSBuffer.wrap(data)); } $writeFile(handle: number, resource: UriComponents, content: VSBuffer, opts: files.FileWriteOptions): Promise { - return Promise.resolve(this.getProvider(handle).writeFile(URI.revive(resource), content.buffer, opts)); + return Promise.resolve(this._getFsProvider(handle).writeFile(URI.revive(resource), content.buffer, opts)); } $delete(handle: number, resource: UriComponents, opts: files.FileDeleteOptions): Promise { - return Promise.resolve(this.getProvider(handle).delete(URI.revive(resource), opts)); + return Promise.resolve(this._getFsProvider(handle).delete(URI.revive(resource), opts)); } $rename(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): Promise { - return Promise.resolve(this.getProvider(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts)); + return Promise.resolve(this._getFsProvider(handle).rename(URI.revive(oldUri), URI.revive(newUri), opts)); } $copy(handle: number, oldUri: UriComponents, newUri: UriComponents, opts: files.FileOverwriteOptions): Promise { - const provider = this.getProvider(handle); + const provider = this._getFsProvider(handle); if (!provider.copy) { throw new Error('FileSystemProvider does not implement "copy"'); } @@ -255,11 +254,11 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $mkdir(handle: number, resource: UriComponents): Promise { - return Promise.resolve(this.getProvider(handle).createDirectory(URI.revive(resource))); + return Promise.resolve(this._getFsProvider(handle).createDirectory(URI.revive(resource))); } $watch(handle: number, session: number, resource: UriComponents, opts: files.IWatchOptions): void { - const subscription = this.getProvider(handle).watch(URI.revive(resource), opts); + const subscription = this._getFsProvider(handle).watch(URI.revive(resource), opts); this._watches.set(session, subscription); } @@ -272,7 +271,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $open(handle: number, resource: UriComponents, opts: files.FileOpenOptions): Promise { - const provider = this.getProvider(handle); + const provider = this._getFsProvider(handle); if (!provider.open) { throw new Error('FileSystemProvider does not implement "open"'); } @@ -280,7 +279,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $close(handle: number, fd: number): Promise { - const provider = this.getProvider(handle); + const provider = this._getFsProvider(handle); if (!provider.close) { throw new Error('FileSystemProvider does not implement "close"'); } @@ -288,7 +287,7 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $read(handle: number, fd: number, pos: number, length: number): Promise { - const provider = this.getProvider(handle); + const provider = this._getFsProvider(handle); if (!provider.read) { throw new Error('FileSystemProvider does not implement "read"'); } @@ -299,14 +298,14 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { } $write(handle: number, fd: number, pos: number, data: VSBuffer): Promise { - const provider = this.getProvider(handle); + const provider = this._getFsProvider(handle); if (!provider.write) { throw new Error('FileSystemProvider does not implement "write"'); } return Promise.resolve(provider.write(fd, pos, data.buffer, 0, data.byteLength)); } - private getProvider(handle: number): vscode.FileSystemProvider { + private _getFsProvider(handle: number): vscode.FileSystemProvider { const provider = this._fsProvider.get(handle); if (!provider) { const err = new Error(); From 1e8412ca2d79aba6c35a0c656f87d6675ce3e08a Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 20 Jun 2019 15:58:16 +0200 Subject: [PATCH 174/364] Update distro hash --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51b6853bd9665..0e3cb54f60796 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "98c55ad448ca078f4eb07091bf54b4cbc189203a", + "distro": "3db6aad4b3378955f6f369ae4a627d68953ed919", "author": { "name": "Microsoft Corporation" }, From 005b19e5bcf9deb0ff6e1cc9273e621f26b6833f Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 16:03:41 +0200 Subject: [PATCH 175/364] introduce VSCODE_STEP_ON_IT --- .../darwin/product-build-darwin.yml | 24 ++++++++++++++- .../linux/product-build-linux-alpine.yml | 20 +++++++++++++ .../linux/product-build-linux-arm.yml | 22 +++++++++++++- .../linux/product-build-linux.yml | 23 +++++++++++++- .../win32/product-build-win32.yml | 30 +++++++++++++++++-- 5 files changed, 114 insertions(+), 5 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index f136f2b449613..201a6bdce4ca6 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -26,18 +26,38 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" git fetch distro git merge $(node -p "require('./package.json').distro") + displayName: Merge distro +- script: | + set -e yarn + displayName: Install dependencies + +- script: | + set -e yarn gulp mixin + displayName: Mix in quality + +- script: | + set -e yarn gulp hygiene yarn monaco-compile-check + displayName: Run hygiene checks + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + +- script: | + set -e node build/azure-pipelines/common/installDistroDependencies.js node build/azure-pipelines/common/installDistroDependencies.js remote node build/lib/builtInExtensions.js - displayName: Prepare build + displayName: Install distro dependencies and extensions - script: | set -e @@ -52,11 +72,13 @@ steps: # APP_NAME="`ls $(agent.builddirectory)/VSCode-darwin | head -n 1`" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME" displayName: Run unit tests + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') - script: | set -e ./scripts/test-integration.sh --build --tfs "Integration Tests" displayName: Run integration tests + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux-alpine.yml b/build/azure-pipelines/linux/product-build-linux-alpine.yml index 4beee37d1a041..71dfb9206777e 100644 --- a/build/azure-pipelines/linux/product-build-linux-alpine.yml +++ b/build/azure-pipelines/linux/product-build-linux-alpine.yml @@ -35,14 +35,34 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" git fetch distro git merge $(node -p "require('./package.json').distro") + displayName: Merge distro +- script: | + set -e CHILD_CONCURRENCY=1 yarn + displayName: Install dependencies + +- script: | + set -e yarn gulp mixin + displayName: Mix in quality + +- script: | + set -e yarn gulp hygiene yarn monaco-compile-check + displayName: Run hygiene checks + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + +- script: | + set -e ./build/azure-pipelines/linux/prebuild-alpine.sh displayName: Prepare build diff --git a/build/azure-pipelines/linux/product-build-linux-arm.yml b/build/azure-pipelines/linux/product-build-linux-arm.yml index 55350cce29537..8eb75c58aa9c3 100644 --- a/build/azure-pipelines/linux/product-build-linux-arm.yml +++ b/build/azure-pipelines/linux/product-build-linux-arm.yml @@ -35,16 +35,36 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" git fetch distro git merge $(node -p "require('./package.json').distro") + displayName: Merge distro +- script: | + set -e CHILD_CONCURRENCY=1 yarn + displayName: Install dependencies + +- script: | + set -e yarn gulp mixin + displayName: Mix in quality + +- script: | + set -e yarn gulp hygiene yarn monaco-compile-check + displayName: Run hygiene checks + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + +- script: | + set -e ./build/azure-pipelines/linux/prebuild-arm.sh - displayName: Prepare build + displayName: Prebuild - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index c1386b93f71f0..691851fbf977f 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -27,18 +27,38 @@ steps: git config user.email "vscode@microsoft.com" git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" git fetch distro git merge $(node -p "require('./package.json').distro") + displayName: Merge distro +- script: | + set -e CHILD_CONCURRENCY=1 yarn + displayName: Install dependencies + +- script: | + set -e yarn gulp mixin + displayName: Mix in quality + +- script: | + set -e yarn gulp hygiene yarn monaco-compile-check + displayName: Run hygiene checks + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + +- script: | + set -e node build/azure-pipelines/common/installDistroDependencies.js node build/azure-pipelines/common/installDistroDependencies.js remote node build/lib/builtInExtensions.js - displayName: Prepare build + displayName: Install distro dependencies and extensions - script: | set -e @@ -56,6 +76,7 @@ steps: DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)" displayName: Run unit tests + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') - script: | set -e diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 339bdde1b9cc4..6505b9a8df248 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -27,18 +27,43 @@ steps: exec { git config user.email "vscode@microsoft.com" } exec { git config user.name "VSCode" } + displayName: Prepare tooling + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" exec { git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" } exec { git fetch distro } exec { git merge $(node -p "require('./package.json').distro") } + displayName: Merge distro +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" exec { yarn } + displayName: Install dependencies + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" exec { yarn gulp mixin } + displayName: Mix in quality + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" exec { yarn gulp hygiene } exec { yarn monaco-compile-check } + displayName: Run hygiene checks + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" exec { node build/azure-pipelines/common/installDistroDependencies.js } exec { node build/azure-pipelines/common/installDistroDependencies.js remote } exec { node build/lib/builtInExtensions.js } - displayName: Prepare build + displayName: Install distro dependencies and extensions - powershell: | . build/azure-pipelines/win32/exec.ps1 @@ -52,8 +77,8 @@ steps: $ErrorActionPreference = "Stop" exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test.bat --build --tfs "Unit Tests" } - # yarn smoketest -- --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" displayName: Run unit tests + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') - powershell: | . build/azure-pipelines/win32/exec.ps1 @@ -61,6 +86,7 @@ steps: exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" } displayName: Run integration tests + condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1 inputs: From c70c399313740bee8f9650ab9570d52d276c65bc Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 20 Jun 2019 16:31:51 +0200 Subject: [PATCH 176/364] remove env scripts fixes #74792 --- scripts/env.ps1 | 3 --- scripts/env.sh | 6 ------ 2 files changed, 9 deletions(-) delete mode 100644 scripts/env.ps1 delete mode 100755 scripts/env.sh diff --git a/scripts/env.ps1 b/scripts/env.ps1 deleted file mode 100644 index 72e094d0a6a1c..0000000000000 --- a/scripts/env.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -$env:npm_config_disturl="https://atom.io/download/electron" -$env:npm_config_target=(node -p "require('./build/lib/electron').getElectronVersion();") -$env:npm_config_runtime="electron" diff --git a/scripts/env.sh b/scripts/env.sh deleted file mode 100755 index 8f641759b2729..0000000000000 --- a/scripts/env.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -export npm_config_disturl=https://atom.io/download/electron -export npm_config_target=$(node -p "require('./build/lib/electron').getElectronVersion();") -export npm_config_runtime=electron -export npm_config_cache="$HOME/.npm-electron" -mkdir -p "$npm_config_cache" From 5c1490f2047e65b7c4735b9279195fbea1c95d52 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 20 Jun 2019 07:36:21 -0700 Subject: [PATCH 177/364] Update xterm.css Fixes #75827 --- .../contrib/terminal/browser/media/xterm.css | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/xterm.css b/src/vs/workbench/contrib/terminal/browser/media/xterm.css index 37429d9646bb8..5bfff739f8d2e 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/xterm.css +++ b/src/vs/workbench/contrib/terminal/browser/media/xterm.css @@ -43,6 +43,8 @@ font-feature-settings: "liga" 0; position: relative; user-select: none; + -ms-user-select: none; + -webkit-user-select: none; } .xterm.focus, @@ -127,13 +129,22 @@ line-height: normal; } +.xterm { + cursor: text; +} + .xterm.enable-mouse-events { - /* When mouse events are enabled (e.g. tmux), revert to the standard pointer cursor */ + /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ cursor: default; } -.xterm:not(.enable-mouse-events) { - cursor: text; +.xterm.xterm-cursor-pointer { + cursor: pointer; +} + +.xterm.column-select.focus { + /* Column selection mode */ + cursor: crosshair; } .xterm .xterm-accessibility, @@ -147,10 +158,6 @@ color: transparent; } -.xterm .xterm-accessibility-tree:focus [id^="xterm-active-item-"] { - outline: 1px solid #F80; -} - .xterm .live-region { position: absolute; left: -9999px; @@ -159,11 +166,10 @@ overflow: hidden; } -.xterm-cursor-pointer { - cursor: pointer !important; +.xterm-dim { + opacity: 0.5; } -.xterm.xterm-cursor-crosshair { - /* Column selection mode */ - cursor: crosshair !important; +.xterm-underline { + text-decoration: underline; } From 210a72c584c54d3a758682ace4b3e36616e74bfc Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Thu, 20 Jun 2019 15:08:28 +0200 Subject: [PATCH 178/364] check if file exists --- .../userData/common/fileUserDataService.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/userData/common/fileUserDataService.ts b/src/vs/workbench/services/userData/common/fileUserDataService.ts index e0690f41ea8a0..6096274dc6dee 100644 --- a/src/vs/workbench/services/userData/common/fileUserDataService.ts +++ b/src/vs/workbench/services/userData/common/fileUserDataService.ts @@ -46,8 +46,18 @@ export class FileUserDataService extends Disposable implements IUserDataService } } - read(key: string): Promise { - return this.fileService.readFile(this.toResource(key)).then(content => content.value.toString()); + async read(key: string): Promise { + const resource = this.toResource(key); + try { + const content = await this.fileService.readFile(resource); + return content.value.toString(); + } catch (e) { + const exists = await this.fileService.exists(resource); + if (exists) { + throw e; + } + } + return ''; } write(key: string, value: string): Promise { From a145fbf2b146165079f1abe8d9ebbdc5e30ce8ba Mon Sep 17 00:00:00 2001 From: isidor Date: Thu, 20 Jun 2019 16:45:38 +0200 Subject: [PATCH 179/364] remove alert, aria-live will read the content even with no focus fixes #41356 --- src/vs/editor/contrib/gotoError/gotoErrorWidget.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts index 968fa5d44cbf3..7d93dc2fb371b 100644 --- a/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts +++ b/src/vs/editor/contrib/gotoError/gotoErrorWidget.ts @@ -25,7 +25,6 @@ import { basename } from 'vs/base/common/resources'; import { IAction } from 'vs/base/common/actions'; import { IActionBarOptions, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar'; import { peekViewTitleForeground, peekViewTitleInfoForeground } from 'vs/editor/contrib/referenceSearch/referencesWidget'; -import * as aria from 'vs/base/browser/ui/aria/aria'; import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon'; class MessageWidget { @@ -286,8 +285,6 @@ export class MarkerNavigationWidget extends PeekViewWidget { this._icon.className = SeverityIcon.className(MarkerSeverity.toSeverity(this._severity)); this.editor.revealPositionInCenter(position, ScrollType.Smooth); - - aria.alert(marker.message); } updateMarker(marker: IMarker): void { From 769e5d2ad21ff30922467f720ad337d4db8fe9c0 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 20 Jun 2019 16:47:17 +0200 Subject: [PATCH 180/364] win code.sh fix --- resources/win32/bin/code.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/win32/bin/code.sh b/resources/win32/bin/code.sh index 606fb108fe5b0..28c48b8d72d2a 100644 --- a/resources/win32/bin/code.sh +++ b/resources/win32/bin/code.sh @@ -11,7 +11,7 @@ VSCODE_PATH="$(dirname "$(dirname "$(realpath "$0")")")" ELECTRON="$VSCODE_PATH/$NAME.exe" if grep -qi Microsoft /proc/version; then # in a wsl shell - if ! [ -z "$WSL_DISTRO_NAME"]; then + if ! [ -z "$WSL_DISTRO_NAME" ]; then # $WSL_DISTRO_NAME is available since WSL builds 18362, also for WSL2 WSL_BUILD=18362 else From 21b21eb6ab2939cadc481d7f9b4ea1833368cb21 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 20 Jun 2019 08:07:04 -0700 Subject: [PATCH 181/364] =?UTF-8?q?=F0=9F=A7=80=20Fix=20#75831?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vs/workbench/browser/media/icons.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/media/icons.css b/src/vs/workbench/browser/media/icons.css index 05465d73aa370..a730544fcb7d9 100644 --- a/src/vs/workbench/browser/media/icons.css +++ b/src/vs/workbench/browser/media/icons.css @@ -67,6 +67,7 @@ body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .t body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Source Control: Git actions"] .icon[data-title="git.refresh"], body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Debug actions"] .icon, body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label^="Extensions"] .icon, +body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.openFile2"], body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.unstage"], body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.stage"], body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.openChange"], From 7b681f8733b003d5eccbdc0c3ef801673caf2df9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 20 Jun 2019 08:22:22 -0700 Subject: [PATCH 182/364] Add proposed api check for shell API Part of #75091 --- src/vs/workbench/api/node/extHost.api.impl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 9898fa25685b2..8818154961399 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -255,6 +255,7 @@ export function createApiFactory( return extHostClipboard; }, get shell() { + checkProposedApiEnabled(extension); return extHostTerminalService.getDefaultShell(configProvider); }, openExternal(uri: URI) { From 106985ac2293ec7d5f23d3453c0801497e963d77 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 20 Jun 2019 17:39:19 +0200 Subject: [PATCH 183/364] launch ext host window internally --- src/vs/platform/windows/common/windows.ts | 1 + .../electron-browser/windowsService.ts | 4 + .../windows/electron-main/windowsService.ts | 11 +++ src/vs/platform/windows/node/windowsIpc.ts | 1 + .../workbench/browser/web.simpleservices.ts | 5 ++ .../debug/browser/debugHelperService.ts | 6 +- .../contrib/debug/browser/debugSession.ts | 8 +- .../contrib/debug/browser/rawDebugSession.ts | 58 +++++++++++-- .../workbench/contrib/debug/common/debug.ts | 17 ---- .../contrib/debug/node/debugHelperService.ts | 83 +------------------ .../workbench/test/workbenchTestServices.ts | 6 +- 11 files changed, 86 insertions(+), 114 deletions(-) diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index 3801a8cc54365..b8cf79dd68d0c 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -153,6 +153,7 @@ export interface IWindowsService { // Global methods openWindow(windowId: number, uris: IURIToOpen[], options: IOpenSettings): Promise; openNewWindow(options?: INewWindowOptions): Promise; + openExtensionDevelopmentHostWindow(args: ParsedArgs): Promise; getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>; getWindowCount(): Promise; log(severity: string, ...messages: string[]): Promise; diff --git a/src/vs/platform/windows/electron-browser/windowsService.ts b/src/vs/platform/windows/electron-browser/windowsService.ts index 73acbb0f67a45..1eb8c60b8ee3a 100644 --- a/src/vs/platform/windows/electron-browser/windowsService.ts +++ b/src/vs/platform/windows/electron-browser/windowsService.ts @@ -195,6 +195,10 @@ export class WindowsService implements IWindowsService { return this.channel.call('openNewWindow', options); } + openExtensionDevelopmentHostWindow(args: ParsedArgs): Promise { + return this.channel.call('openExtensionDevelopmentHostWindow', args); + } + async getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> { const result = await this.channel.call<{ id: number; diff --git a/src/vs/platform/windows/electron-main/windowsService.ts b/src/vs/platform/windows/electron-main/windowsService.ts index ed90804f293bb..1c3c4734384c3 100644 --- a/src/vs/platform/windows/electron-main/windowsService.ts +++ b/src/vs/platform/windows/electron-main/windowsService.ts @@ -306,6 +306,17 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH this.windowsMainService.openNewWindow(OpenContext.API, options); } + async openExtensionDevelopmentHostWindow(args: ParsedArgs): Promise { + this.logService.trace('windowsService#openExtensionDevelopmentHostWindow ' + JSON.stringify(args)); + + if (args.extensionDevelopmentPath) { + this.windowsMainService.openExtensionDevelopmentHostWindow(args.extensionDevelopmentPath, { + context: OpenContext.API, + cli: args + }); + } + } + async getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> { this.logService.trace('windowsService#getWindows'); diff --git a/src/vs/platform/windows/node/windowsIpc.ts b/src/vs/platform/windows/node/windowsIpc.ts index c12c47b5a3aeb..30876b55e1054 100644 --- a/src/vs/platform/windows/node/windowsIpc.ts +++ b/src/vs/platform/windows/node/windowsIpc.ts @@ -102,6 +102,7 @@ export class WindowsChannel implements IServerChannel { return this.service.openWindow(arg[0], urisToOpen, options); } case 'openNewWindow': return this.service.openNewWindow(arg); + case 'openExtensionDevelopmentHostWindow': return this.service.openExtensionDevelopmentHostWindow(arg); case 'getWindows': return this.service.getWindows(); case 'getWindowCount': return this.service.getWindowCount(); case 'relaunch': return this.service.relaunch(arg[0]); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 96d6991045614..b6cf7746407fb 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -45,6 +45,7 @@ import { CommentingRanges } from 'vs/editor/common/modes'; import { Range } from 'vs/editor/common/core/range'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { ParsedArgs } from 'vs/platform/environment/common/environment'; //#region Backup File @@ -1052,6 +1053,10 @@ export class SimpleWindowsService implements IWindowsService { return Promise.resolve(); } + openExtensionDevelopmentHostWindow(args: ParsedArgs): Promise { + return Promise.resolve(); + } + getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> { return Promise.resolve([]); } diff --git a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts b/src/vs/workbench/contrib/debug/browser/debugHelperService.ts index c7fa5b96cd19f..be123b31a5e6e 100644 --- a/src/vs/workbench/contrib/debug/browser/debugHelperService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugHelperService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ServiceIdentifier, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ITerminalLauncher, IDebugHelperService, ILaunchVSCodeArguments } from 'vs/workbench/contrib/debug/common/debug'; +import { ITerminalLauncher, IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -17,10 +17,6 @@ export class BrowserDebugHelperService implements IDebugHelperService { throw new Error('Method createTerminalLauncher not implemented.'); } - launchVsCode(vscodeArgs: ILaunchVSCodeArguments): Promise { - throw new Error('Method launchVsCode not implemented.'); - } - createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { return undefined; } diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index da945a8ee9fa6..a75db88dfc8a8 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -12,7 +12,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { CompletionItem, completionKindFromString } from 'vs/editor/common/modes'; import { Position } from 'vs/editor/common/core/position'; import * as aria from 'vs/base/browser/ui/aria/aria'; -import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource, IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugSession, IConfig, IThread, IRawModelUpdate, IDebugService, IRawStoppedDetails, State, LoadedSourceEvent, IFunctionBreakpoint, IExceptionBreakpoint, IBreakpoint, IExceptionInfo, AdapterEndEvent, IDebugger, VIEWLET_ID, IDebugConfiguration, IReplElement, IStackFrame, IExpression, IReplElementSource } from 'vs/workbench/contrib/debug/common/debug'; import { Source } from 'vs/workbench/contrib/debug/common/debugSource'; import { mixin } from 'vs/base/common/objects'; import { Thread, ExpressionContainer, DebugModel } from 'vs/workbench/contrib/debug/common/debugModel'; @@ -22,7 +22,7 @@ import { IWorkspaceFolder, IWorkspaceContextService } from 'vs/platform/workspac import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { RunOnceScheduler } from 'vs/base/common/async'; import { generateUuid } from 'vs/base/common/uuid'; -import { IWindowService } from 'vs/platform/windows/common/windows'; +import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { normalizeDriveLetter } from 'vs/base/common/labels'; import { Range } from 'vs/editor/common/core/range'; @@ -68,7 +68,7 @@ export class DebugSession implements IDebugSession { @INotificationService private readonly notificationService: INotificationService, @ISignService private readonly signService: ISignService, @IProductService private readonly productService: IProductService, - @IDebugHelperService private readonly debugUIService: IDebugHelperService + @IWindowsService private readonly windowsService: IWindowsService ) { this.id = generateUuid(); this.repl = new ReplModel(this); @@ -169,7 +169,7 @@ export class DebugSession implements IDebugSession { return dbgr.createDebugAdapter(this).then(debugAdapter => { - this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.signService, this.debugUIService); + this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.signService, this.windowsService); return this.raw!.start().then(() => { diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index 3eb52275d437a..7839a60d19e1e 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -9,10 +9,28 @@ import * as objects from 'vs/base/common/objects'; import { Action } from 'vs/base/common/actions'; import * as errors from 'vs/base/common/errors'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { formatPII } from 'vs/workbench/contrib/debug/common/debugUtils'; -import { IDebugAdapter, IConfig, AdapterEndEvent, IDebugger, IDebugHelperService, ILaunchVSCodeArguments } from 'vs/workbench/contrib/debug/common/debug'; +import { formatPII, isUri } from 'vs/workbench/contrib/debug/common/debugUtils'; +import { IDebugAdapter, IConfig, AdapterEndEvent, IDebugger } from 'vs/workbench/contrib/debug/common/debug'; import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { ParsedArgs } from 'vs/platform/environment/common/environment'; +import { IWindowsService } from 'vs/platform/windows/common/windows'; +import { URI } from 'vs/base/common/uri'; + +/** + * This interface represents a single command line argument split into a "prefix" and a "path" half. + * The optional "prefix" contains arbitrary text and the optional "path" contains a file system path. + * Concatenating both results in the original command line argument. + */ +interface ILaunchVSCodeArgument { + prefix?: string; + path?: string; +} + +interface ILaunchVSCodeArguments { + args: ILaunchVSCodeArgument[]; + env?: { [key: string]: string | null; }; +} /** * Encapsulates the DebugAdapter lifecycle and some idiosyncrasies of the Debug Adapter Protocol. @@ -56,7 +74,8 @@ export class RawDebugSession { private readonly telemetryService: ITelemetryService, public readonly customTelemetryService: ITelemetryService | undefined, private readonly signService: ISignService, - private readonly debugUIService: IDebugHelperService + private readonly windowsService: IWindowsService + ) { this.debugAdapter = debugAdapter; this._capabilities = Object.create(null); @@ -503,9 +522,9 @@ export class RawDebugSession { switch (request.command) { case 'launchVSCode': - this.debugUIService.launchVsCode(request.arguments).then(pid => { + this.launchVsCode(request.arguments).then(_ => { response.body = { - processId: pid + //processId: pid }; safeSendResponse(response); }, err => { @@ -549,6 +568,35 @@ export class RawDebugSession { } } + private launchVsCode(vscodeArgs: ILaunchVSCodeArguments): Promise { + + let args: ParsedArgs = { + _: [] + }; + + for (let arg of vscodeArgs.args) { + if (arg.prefix) { + const a2 = (arg.prefix || '') + (arg.path || ''); + const match = /^--(.+)=(.+)$/.exec(a2); + if (match && match.length === 3) { + const key = match[1]; + let value = match[2]; + + if ((key === 'file-uri' || key === 'folder-uri') && !isUri(arg.path)) { + value = URI.file(value).toString(); + } + + args[key] = value; + + } else { + args._.push(a2); + } + } + } + + return this.windowsService.openExtensionDevelopmentHostWindow(args); + } + private send(command: string, args: any, timeout?: number): Promise { return new Promise((completeDispatch, errorDispatch) => { if (!this.debugAdapter) { diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index da0718b23db4c..f36d6529d77bb 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -843,27 +843,10 @@ export interface IDebugEditorContribution extends IEditorContribution { export const DEBUG_HELPER_SERVICE_ID = 'debugHelperService'; export const IDebugHelperService = createDecorator(DEBUG_HELPER_SERVICE_ID); -/** - * This interface represents a single command line argument split into a "prefix" and a "path" half. - * The optional "prefix" contains arbitrary text and the optional "path" contains a file system path. - * Concatenating both results in the original command line argument. - */ -export interface ILaunchVSCodeArgument { - prefix?: string; - path?: string; -} - -export interface ILaunchVSCodeArguments { - args: ILaunchVSCodeArgument[]; - env?: { [key: string]: string | null; }; -} - export interface IDebugHelperService { _serviceBrand: any; createTerminalLauncher(instantiationService: IInstantiationService): ITerminalLauncher; - launchVsCode(vscodeArgs: ILaunchVSCodeArguments): Promise; - createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined; } diff --git a/src/vs/workbench/contrib/debug/node/debugHelperService.ts b/src/vs/workbench/contrib/debug/node/debugHelperService.ts index cfbc35391890b..76fcf6e30e857 100644 --- a/src/vs/workbench/contrib/debug/node/debugHelperService.ts +++ b/src/vs/workbench/contrib/debug/node/debugHelperService.ts @@ -3,13 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as objects from 'vs/base/common/objects'; -import { isUri } from 'vs/workbench/contrib/debug/common/debugUtils'; -import * as cp from 'child_process'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { TerminalLauncher } from 'vs/workbench/contrib/debug/node/terminalSupport'; -import { ITerminalLauncher, IDebugHelperService, ILaunchVSCodeArguments } from 'vs/workbench/contrib/debug/common/debug'; +import { ITerminalLauncher, IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; import { Client as TelemetryClient } from 'vs/base/parts/ipc/node/ipc.cp'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; import { getPathFromAmdModule } from 'vs/base/common/amd'; @@ -21,7 +17,6 @@ export class NodeDebugHelperService implements IDebugHelperService { _serviceBrand: any; constructor( - @IEnvironmentService private readonly environmentService: IEnvironmentService ) { } @@ -29,82 +24,6 @@ export class NodeDebugHelperService implements IDebugHelperService { return instantiationService.createInstance(TerminalLauncher); } - launchVsCode(vscodeArgs: ILaunchVSCodeArguments): Promise { - - const spawnOpts: cp.SpawnOptions = { - detached: false // https://github.com/Microsoft/vscode/issues/57018 - }; - - if (vscodeArgs.env) { - // merge environment variables into a copy of the process.env - const envArgs = objects.mixin(objects.mixin({}, process.env), vscodeArgs.env); - // and delete some if necessary - Object.keys(envArgs).filter(k => envArgs[k] === null).forEach(key => delete envArgs[key]); - spawnOpts.env = envArgs; - } - - let spawnArgs = vscodeArgs.args.map(a => { - if ((a.prefix === '--file-uri=' || a.prefix === '--folder-uri=') && !isUri(a.path)) { - return (a.path || ''); - } - return (a.prefix || '') + (a.path || ''); - }); - - let runtimeExecutable = this.environmentService['execPath']; - if (!runtimeExecutable) { - return Promise.reject(new Error(`VS Code executable unknown`)); - } - - // if VS Code runs out of sources, add the VS Code workspace path as the first argument so that Electron turns into VS Code - const electronIdx = runtimeExecutable.indexOf(process.platform === 'win32' ? '\\.build\\electron\\' : '/.build/electron/'); - if (electronIdx > 0) { - // guess the VS Code workspace path from the executable - const vscodeWorkspacePath = runtimeExecutable.substr(0, electronIdx); - - // only add VS Code workspace path if user hasn't already added that path as a (folder) argument - const x = spawnArgs.filter(a => a.indexOf(vscodeWorkspacePath) === 0); - if (x.length === 0) { - spawnArgs.unshift(vscodeWorkspacePath); - } - } - - // Workaround for bug Microsoft/vscode#45832 - if (process.platform === 'win32' && runtimeExecutable.indexOf(' ') > 0) { - let foundArgWithSpace = false; - - // check whether there is one arg with a space - const args: string[] = []; - for (const a of spawnArgs) { - if (a.indexOf(' ') > 0) { - args.push(`"${a}"`); - foundArgWithSpace = true; - } else { - args.push(a); - } - } - - if (foundArgWithSpace) { - spawnArgs = args; - runtimeExecutable = `"${runtimeExecutable}"`; - spawnOpts.shell = true; - } - } - - return new Promise((resolve, reject) => { - const process = cp.spawn(runtimeExecutable, spawnArgs, spawnOpts); - process.on('error', error => { - reject(error); - }); - process.on('exit', code => { - if (code === 0) { - resolve(process.pid); - } else { - reject(new Error(`VS Code exited with ${code}`)); - } - }); - }); - } - createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { const client = new TelemetryClient( diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 209a39fd4a57b..01b3c98401c73 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -38,7 +38,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { IWindowsService, IWindowService, INativeOpenDialogOptions, IEnterWorkspaceResult, IMessageBoxResult, MenuBarVisibility, IURIToOpen, IOpenSettings, IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; @@ -1447,6 +1447,10 @@ export class TestWindowsService implements IWindowsService { return Promise.resolve(); } + openExtensionDevelopmentHostWindow(args: ParsedArgs): Promise { + return Promise.resolve(); + } + getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> { throw new Error('not implemented'); } From e83bb4ba9a6134996d5848d81fbe40ab39069caa Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Thu, 20 Jun 2019 18:04:34 +0200 Subject: [PATCH 184/364] EH debugging: support multiple files and folders --- .../contrib/debug/browser/rawDebugSession.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts index 7839a60d19e1e..b4828af8340f2 100644 --- a/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/rawDebugSession.ts @@ -584,9 +584,21 @@ export class RawDebugSession { if ((key === 'file-uri' || key === 'folder-uri') && !isUri(arg.path)) { value = URI.file(value).toString(); - } - args[key] = value; + const v = args[key]; + if (v) { + if (Array.isArray(v)) { + v.push(value); + } else { + args[key] = [v, value]; + } + } else { + args[key] = value; + } + + } else { + args[key] = value; + } } else { args._.push(a2); From 7970fddc5b3f9b79750b59e54dbf0561101f963a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 20 Jun 2019 09:30:47 -0700 Subject: [PATCH 185/364] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0e3cb54f60796..f25abb8d43103 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "3db6aad4b3378955f6f369ae4a627d68953ed919", + "distro": "cb72005ab15a4d369209542fbfa4e64c06db2111", "author": { "name": "Microsoft Corporation" }, From 95fa2fe80d957ac6547e92f395a1aafed474b13b Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 20 Jun 2019 09:34:17 -0700 Subject: [PATCH 186/364] xterm@3.15.0-beta50 Diff: https://github.com/xtermjs/xterm.js/compare/846a189...96eafd3 Changes: - Publish improvements - Layering/strict updates --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f25abb8d43103..f897c765b8374 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "vscode-ripgrep": "^1.2.5", "vscode-sqlite3": "4.0.7", "vscode-textmate": "^4.1.1", - "xterm": "3.15.0-beta42", + "xterm": "3.15.0-beta50", "xterm-addon-search": "0.1.0-beta6", "xterm-addon-web-links": "0.1.0-beta10", "yauzl": "^2.9.2", diff --git a/yarn.lock b/yarn.lock index 4d4f75a05f7d4..107c1f0fd3766 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9802,10 +9802,10 @@ xterm-addon-web-links@0.1.0-beta10: resolved "https://registry.yarnpkg.com/xterm-addon-web-links/-/xterm-addon-web-links-0.1.0-beta10.tgz#610fa9773a2a5ccd41c1c83ba0e2dd2c9eb66a23" integrity sha512-xfpjy0V6bB4BR44qIgZQPoCMVakxb65gMscPkHpO//QxvUxKzabV3dxOsIbeZRFkUGsWTFlvz2OoaBLoNtv5gg== -xterm@3.15.0-beta42: - version "3.15.0-beta42" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta42.tgz#8ed1f2928d46cb5f941dc39e4116782787a4b8a6" - integrity sha512-1hXcdnrhAsvmyTrcR+cz/B3O/Bv9oRRg4lPrOVoJkW+0otRfljJ5CHMfaL0uiZwphNoWpkHXrzApsY5GzS8o5Q== +xterm@3.15.0-beta50: + version "3.15.0-beta50" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta50.tgz#6413057fe36ff5808a41eba337f83076144d5c10" + integrity sha512-LAJ8kP3U8oXnVR3uaL4NxNFKcFDt3Zoec53hgYppwW8P5LdmL/dc0eDpgqiEsPLx4GgD37d8J92EcoMzKs2vVw== y18n@^3.2.1: version "3.2.1" From 62037fb7bcf25914ecb0cfee1a7290ed8af74622 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 20 Jun 2019 10:03:21 -0700 Subject: [PATCH 187/364] Fire onDidChangeMaximumDimension when dimensions are set Fixes #73496 --- .../api/browser/mainThreadTerminalService.ts | 5 +++++ src/vs/workbench/api/common/extHost.protocol.ts | 1 + .../api/node/extHostTerminalService.ts | 5 +++++ .../terminal/browser/terminalInstance.ts | 17 ++++++++++++++--- .../contrib/terminal/common/terminal.ts | 7 ++++--- .../contrib/terminal/common/terminalService.ts | 3 +++ 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index ff3183d07128d..a607cab17b615 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -42,6 +42,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.push(_terminalService.onInstanceDisposed(instance => this._onTerminalDisposed(instance))); this._toDispose.push(_terminalService.onInstanceProcessIdReady(instance => this._onTerminalProcessIdReady(instance))); this._toDispose.push(_terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance))); + this._toDispose.push(_terminalService.onInstanceMaximumDimensionsChanged(instance => this._onInstanceMaximumDimensionsChanged(instance))); this._toDispose.push(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request))); this._toDispose.push(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); this._toDispose.push(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); @@ -226,6 +227,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._proxy.$acceptTerminalDimensions(instance.id, instance.cols, instance.rows); } + private _onInstanceMaximumDimensionsChanged(instance: ITerminalInstance): void { + this._proxy.$acceptTerminalMaximumDimensions(instance.id, instance.maxCols, instance.maxRows); + } + private _onTerminalRequestExtHostProcess(request: ITerminalProcessExtHostRequest): void { // Only allow processes on remote ext hosts if (!this._remoteAuthority) { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index df31280ffc898..58ec9762b80f0 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1126,6 +1126,7 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalRendererInput(id: number, data: string): void; $acceptTerminalTitleChange(id: number, name: string): void; $acceptTerminalDimensions(id: number, cols: number, rows: number): void; + $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void; $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; $acceptProcessInput(id: number, data: string): void; $acceptProcessResize(id: number, cols: number, rows: number): void; diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index e935ccdf20d4b..d0d8920c25cf8 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -409,6 +409,11 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { }); } } + }); + } + + public $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void { + this._getTerminalByIdEventually(id).then(() => { // When a terminal's dimensions change, a renderer's _maximum_ dimensions change const renderer = this._getTerminalRendererById(id); if (renderer) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 9584762836c7c..95c3afd044527 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -201,6 +201,8 @@ export class TerminalInstance implements ITerminalInstance { } return this._rows; } + public get maxCols(): number { return this._cols; } + public get maxRows(): number { return this._rows; } // TODO: Ideally processId would be merged into processReady public get processId(): number | undefined { return this._processManager ? this._processManager.shellProcessId : undefined; } // TODO: How does this work with detached processes? @@ -232,6 +234,8 @@ export class TerminalInstance implements ITerminalInstance { public get onRequestExtHostProcess(): Event { return this._onRequestExtHostProcess.event; } private readonly _onDimensionsChanged = new Emitter(); public get onDimensionsChanged(): Event { return this._onDimensionsChanged.event; } + private readonly _onMaximumDimensionsChanged = new Emitter(); + public get onMaximumDimensionsChanged(): Event { return this._onMaximumDimensionsChanged.event; } private readonly _onFocus = new Emitter(); public get onFocus(): Event { return this._onFocus.event; } @@ -349,12 +353,20 @@ export class TerminalInstance implements ITerminalInstance { } else { scaledCharWidth = Math.floor(font.charWidth * window.devicePixelRatio) + font.letterSpacing; } - this._cols = Math.max(Math.floor(scaledWidthAvailable / scaledCharWidth), 1); + const newCols = Math.max(Math.floor(scaledWidthAvailable / scaledCharWidth), 1); const scaledHeightAvailable = dimension.height * window.devicePixelRatio; const scaledCharHeight = Math.ceil(font.charHeight * window.devicePixelRatio); const scaledLineHeight = Math.floor(scaledCharHeight * font.lineHeight); - this._rows = Math.max(Math.floor(scaledHeightAvailable / scaledLineHeight), 1); + const newRows = Math.max(Math.floor(scaledHeightAvailable / scaledLineHeight), 1); + + if (this._cols !== newCols || this._rows !== newRows) { + this._cols = newCols; + this._rows = newRows; + if (this.shellLaunchConfig.isRendererOnly) { + this._onMaximumDimensionsChanged.fire(); + } + } return dimension.width; } @@ -1238,7 +1250,6 @@ export class TerminalInstance implements ITerminalInstance { return; } - const terminalWidth = this._evaluateColsAndRows(dimension.width, dimension.height); if (!terminalWidth) { return; diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 2c49b9dff8e74..a241d24ace059 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -221,6 +221,7 @@ export interface ITerminalService { onInstanceDisposed: Event; onInstanceProcessIdReady: Event; onInstanceDimensionsChanged: Event; + onInstanceMaximumDimensionsChanged: Event; onInstanceRequestExtHostProcess: Event; onInstancesChanged: Event; onInstanceTitleChanged: Event; @@ -377,6 +378,8 @@ export interface ITerminalInstance { readonly cols: number; readonly rows: number; + readonly maxCols: number; + readonly maxRows: number; /** * The process ID of the shell process, this is undefined when there is no process associated @@ -395,12 +398,10 @@ export interface ITerminalInstance { onDisposed: Event; onFocused: Event; - onProcessIdReady: Event; - onRequestExtHostProcess: Event; - onDimensionsChanged: Event; + onMaximumDimensionsChanged: Event; onFocus: Event; diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 2dd2c47180ca9..1f8e90b6407a5 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -57,6 +57,8 @@ export abstract class TerminalService implements ITerminalService { public get onInstanceRequestExtHostProcess(): Event { return this._onInstanceRequestExtHostProcess.event; } protected readonly _onInstanceDimensionsChanged = new Emitter(); public get onInstanceDimensionsChanged(): Event { return this._onInstanceDimensionsChanged.event; } + protected readonly _onInstanceMaximumDimensionsChanged = new Emitter(); + public get onInstanceMaximumDimensionsChanged(): Event { return this._onInstanceMaximumDimensionsChanged.event; } protected readonly _onInstancesChanged = new Emitter(); public get onInstancesChanged(): Event { return this._onInstancesChanged.event; } protected readonly _onInstanceTitleChanged = new Emitter(); @@ -384,6 +386,7 @@ export abstract class TerminalService implements ITerminalService { instance.addDisposable(instance.onTitleChanged(this._onInstanceTitleChanged.fire, this._onInstanceTitleChanged)); instance.addDisposable(instance.onProcessIdReady(this._onInstanceProcessIdReady.fire, this._onInstanceProcessIdReady)); instance.addDisposable(instance.onDimensionsChanged(() => this._onInstanceDimensionsChanged.fire(instance))); + instance.addDisposable(instance.onMaximumDimensionsChanged(() => this._onInstanceMaximumDimensionsChanged.fire(instance))); instance.addDisposable(instance.onFocus(this._onActiveInstanceChanged.fire, this._onActiveInstanceChanged)); } From 338b466e9504af0663e9ea66531459ea3e55416f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Jun 2019 11:08:17 -0700 Subject: [PATCH 188/364] Fix potential race --- .../workbench/contrib/webview/browser/pre/main.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 971cbc0de23ef..b46a63a7c8f5e 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -122,15 +122,15 @@ if (navigator.serviceWorker) { navigator.serviceWorker.register('service-worker.js'); - navigator.serviceWorker.ready.then(registration => { - function forwardFromHostToWorker(channel) { - host.onMessage(channel, event => { + function forwardFromHostToWorker(channel) { + host.onMessage(channel, event => { + navigator.serviceWorker.ready.then(registration => { registration.active.postMessage({ channel: channel, data: event.data.args }); }); - } - forwardFromHostToWorker('did-load-resource'); - forwardFromHostToWorker('did-load-localhost'); - }); + }); + } + forwardFromHostToWorker('did-load-resource'); + forwardFromHostToWorker('did-load-localhost'); navigator.serviceWorker.addEventListener('message', event => { if (['load-resource', 'load-localhost'].includes(event.data.channel)) { From 0112fd31bcc827e0cd53cfdbc90033add07e5fda Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Jun 2019 13:48:23 -0700 Subject: [PATCH 189/364] Delete cached service worker entries after a short timeout --- .../webview/browser/pre/service-worker.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index d6154ba645d82..d36d3cca24e6b 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -7,6 +7,8 @@ */ const resourceRoot = '/vscode-resource'; +const resolveTimeout = 30000; + /** * @template T * @typedef {{ @@ -36,6 +38,7 @@ class RequestStore { /** * @param {string} webviewId * @param {string} path + * @returns {Promise} */ create(webviewId, path) { const existing = this.get(webviewId, path); @@ -44,7 +47,17 @@ class RequestStore { } let resolve; const promise = new Promise(r => resolve = r); - this.map.set(this._key(webviewId, path), { resolve, promise }); + const entry = { resolve, promise }; + this.map.set(this._key(webviewId, path), entry); + + const dispose = () => { + clearTimeout(timeout); + const existing = this.get(webviewId, path); + if (existing === entry) { + return this.map.delete(this._key(webviewId, path)); + } + }; + const timeout = setTimeout(dispose, resolveTimeout); return promise; } @@ -91,7 +104,6 @@ const notFoundResponse = new Response('Not Found', { status: 404, }); - self.addEventListener('message', (event) => { switch (event.data.channel) { case 'did-load-resource': From 7679015e6f482b1733131d729d3dbfdb26579d0a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 19 Jun 2019 15:51:50 -0700 Subject: [PATCH 190/364] Fix webview developer command not being registered --- .../electron-browser/webview.contribution.ts | 13 ++++++++++++- .../electron-browser/{pre => }/webviewCommands.ts | 12 +----------- 2 files changed, 13 insertions(+), 12 deletions(-) rename src/vs/workbench/contrib/webview/electron-browser/{pre => }/webviewCommands.ts (60%) diff --git a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts index 7b7b2c2dc7662..cd9127089895d 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webview.contribution.ts @@ -3,8 +3,19 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IWebviewService } from 'vs/workbench/contrib/webview/common/webview'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; +import { IWebviewService, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview'; import { WebviewService } from 'vs/workbench/contrib/webview/electron-browser/webviewService'; +import { OpenWebviewDeveloperToolsAction } from 'vs/workbench/contrib/webview/electron-browser/webviewCommands'; registerSingleton(IWebviewService, WebviewService, true); + +const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); + +actionRegistry.registerWorkbenchAction( + new SyncActionDescriptor(OpenWebviewDeveloperToolsAction, OpenWebviewDeveloperToolsAction.ID, OpenWebviewDeveloperToolsAction.LABEL), + OpenWebviewDeveloperToolsAction.ALIAS, + webviewDeveloperCategory); diff --git a/src/vs/workbench/contrib/webview/electron-browser/pre/webviewCommands.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts similarity index 60% rename from src/vs/workbench/contrib/webview/electron-browser/pre/webviewCommands.ts rename to src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts index 40ce157e4c480..e239b767855b8 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/pre/webviewCommands.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewCommands.ts @@ -5,13 +5,10 @@ import { Action } from 'vs/base/common/actions'; import * as nls from 'vs/nls'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; -import { webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview'; export class OpenWebviewDeveloperToolsAction extends Action { static readonly ID = 'workbench.action.webview.openDeveloperTools'; + static readonly ALIAS = 'Open Webview Developer Tools'; static readonly LABEL = nls.localize('openToolsLabel', "Open Webview Developer Tools"); public constructor(id: string, label: string) { @@ -30,10 +27,3 @@ export class OpenWebviewDeveloperToolsAction extends Action { return Promise.resolve(true); } } - -const actionRegistry = Registry.as(ActionExtensions.WorkbenchActions); - -actionRegistry.registerWorkbenchAction( - new SyncActionDescriptor(OpenWebviewDeveloperToolsAction, OpenWebviewDeveloperToolsAction.ID, OpenWebviewDeveloperToolsAction.LABEL), - 'Open Webview Developer Tools', - webviewDeveloperCategory); From 8b93c01655639f80a71caff226ad3048e7cc2be0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 00:18:25 -0700 Subject: [PATCH 191/364] Re-queue canceled geterr requests before remaining buffers We should give higher priority to files that have previously had geterr triggered on them but did not have their request completed --- .../src/features/bufferSyncSupport.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts index e730f8e8be659..25ffb4c81bd2d 100644 --- a/extensions/typescript-language-features/src/features/bufferSyncSupport.ts +++ b/extensions/typescript-language-features/src/features/bufferSyncSupport.ts @@ -470,20 +470,20 @@ export default class BufferSyncSupport extends Disposable { private sendPendingDiagnostics(): void { const orderedFileSet = this.pendingDiagnostics.getOrderedFileSet(); + if (this.pendingGetErr) { + this.pendingGetErr.cancel(); + + for (const file of this.pendingGetErr.files.entries) { + orderedFileSet.set(file.resource, undefined); + } + } + // Add all open TS buffers to the geterr request. They might be visible for (const buffer of this.syncedBuffers.values) { orderedFileSet.set(buffer.resource, undefined); } if (orderedFileSet.size) { - if (this.pendingGetErr) { - this.pendingGetErr.cancel(); - - for (const file of this.pendingGetErr.files.entries) { - orderedFileSet.set(file.resource, undefined); - } - } - const getErr = this.pendingGetErr = GetErrRequest.executeGetErrRequest(this.client, orderedFileSet, () => { if (this.pendingGetErr === getErr) { this.pendingGetErr = undefined; From 247d61f4f10062f169211eb38d465b9e09dce756 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 10:27:22 -0700 Subject: [PATCH 192/364] Remove log uploader Fixes #75748 --- resources/completions/bash/code | 2 +- resources/completions/zsh/_code | 1 - src/vs/code/electron-main/logUploader.ts | 153 ------------------ src/vs/code/electron-main/main.ts | 20 +-- src/vs/code/node/cli.ts | 6 +- .../environment/common/environment.ts | 1 - src/vs/platform/environment/node/argv.ts | 1 - 7 files changed, 4 insertions(+), 180 deletions(-) delete mode 100644 src/vs/code/electron-main/logUploader.ts diff --git a/resources/completions/bash/code b/resources/completions/bash/code index e377c5d24e23c..f40963db05c3c 100644 --- a/resources/completions/bash/code +++ b/resources/completions/bash/code @@ -50,7 +50,7 @@ _code() --uninstall-extension --enable-proposed-api --verbose --log -s --status -p --performance --prof-startup --disable-extensions --disable-extension --inspect-extensions - --inspect-brk-extensions --disable-gpu --upload-logs + --inspect-brk-extensions --disable-gpu --max-memory=' -- "$cur") ) [[ $COMPREPLY == *= ]] && compopt -o nospace return diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 9579cffb2f64c..8c4415ac59f0d 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -30,7 +30,6 @@ arguments=( '--inspect-extensions[allow debugging and profiling of extensions]' '--inspect-brk-extensions[allow debugging and profiling of extensions with the extension host being paused after start]' '--disable-gpu[disable GPU hardware acceleration]' - '--upload-logs[upload logs from current session to a secure endpoint]:confirm:(iConfirmLogsUpload)' '--max-memory=[max memory size for a window (in Mbytes)]:size (Mbytes)' '*:file or directory:_files' ) diff --git a/src/vs/code/electron-main/logUploader.ts b/src/vs/code/electron-main/logUploader.ts deleted file mode 100644 index 4e601fe8a6515..0000000000000 --- a/src/vs/code/electron-main/logUploader.ts +++ /dev/null @@ -1,153 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as os from 'os'; -import * as cp from 'child_process'; -import * as fs from 'fs'; - -import * as path from 'vs/base/common/path'; -import { localize } from 'vs/nls'; -import product from 'vs/platform/product/node/product'; -import { IRequestService } from 'vs/platform/request/node/request'; -import { IRequestContext } from 'vs/base/node/request'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { CancellationToken } from 'vs/base/common/cancellation'; -import { ILaunchService } from 'vs/platform/launch/electron-main/launchService'; - -interface PostResult { - readonly blob_id: string; -} - -class Endpoint { - private constructor( - readonly url: string - ) { } - - static getFromProduct(): Endpoint | undefined { - const logUploaderUrl = product.logUploaderUrl; - return logUploaderUrl ? new Endpoint(logUploaderUrl) : undefined; - } -} - -export async function uploadLogs( - launchService: ILaunchService, - requestService: IRequestService, - environmentService: IEnvironmentService -): Promise { - const endpoint = Endpoint.getFromProduct(); - if (!endpoint) { - console.error(localize('invalidEndpoint', 'Invalid log uploader endpoint')); - return; - } - - const logsPath = await launchService.getLogsPath(); - - if (await promptUserToConfirmLogUpload(logsPath, environmentService)) { - console.log(localize('beginUploading', 'Uploading...')); - const outZip = await zipLogs(logsPath); - const result = await postLogs(endpoint, outZip, requestService); - console.log(localize('didUploadLogs', 'Upload successful! Log file ID: {0}', result.blob_id)); - } -} - -function promptUserToConfirmLogUpload( - logsPath: string, - environmentService: IEnvironmentService -): boolean { - const confirmKey = 'iConfirmLogsUpload'; - if ((environmentService.args['upload-logs'] || '').toLowerCase() === confirmKey.toLowerCase()) { - return true; - } else { - const message = localize('logUploadPromptHeader', 'You are about to upload your session logs to a secure Microsoft endpoint that only Microsoft\'s members of the VS Code team can access.') - + '\n\n' + localize('logUploadPromptBody', 'Session logs may contain personal information such as full paths or file contents. Please review and redact your session log files here: \'{0}\'', logsPath) - + '\n\n' + localize('logUploadPromptBodyDetails', 'By continuing you confirm that you have reviewed and redacted your session log files and that you agree to Microsoft using them to debug VS Code.') - + '\n\n' + localize('logUploadPromptAcceptInstructions', 'Please run code with \'--upload-logs={0}\' to proceed with upload', confirmKey); - console.log(message); - return false; - } -} - -async function postLogs( - endpoint: Endpoint, - outZip: string, - requestService: IRequestService -): Promise { - const dotter = setInterval(() => console.log('.'), 5000); - let result: IRequestContext; - try { - result = await requestService.request({ - url: endpoint.url, - type: 'POST', - data: Buffer.from(fs.readFileSync(outZip)).toString('base64'), - headers: { - 'Content-Type': 'application/zip' - } - }, CancellationToken.None); - } catch (e) { - clearInterval(dotter); - console.log(localize('postError', 'Error posting logs: {0}', e)); - throw e; - } - - return new Promise((resolve, reject) => { - const parts: Buffer[] = []; - result.stream.on('data', data => { - parts.push(data); - }); - - result.stream.on('end', () => { - clearInterval(dotter); - try { - const response = Buffer.concat(parts).toString('utf-8'); - if (result.res.statusCode === 200) { - resolve(JSON.parse(response)); - } else { - const errorMessage = localize('responseError', 'Error posting logs. Got {0} — {1}', result.res.statusCode, response); - console.log(errorMessage); - reject(new Error(errorMessage)); - } - } catch (e) { - console.log(localize('parseError', 'Error parsing response')); - reject(e); - } - }); - }); -} - -function zipLogs( - logsPath: string -): Promise { - const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vscode-log-upload')); - const outZip = path.join(tempDir, 'logs.zip'); - return new Promise((resolve, reject) => { - doZip(logsPath, outZip, tempDir, (err, stdout, stderr) => { - if (err) { - console.error(localize('zipError', 'Error zipping logs: {0}', err.message)); - reject(err); - } else { - resolve(outZip); - } - }); - }); -} - -function doZip( - logsPath: string, - outZip: string, - tempDir: string, - callback: (error: Error, stdout: string, stderr: string) => void -) { - switch (os.platform()) { - case 'win32': - // Copy directory first to avoid file locking issues - const sub = path.join(tempDir, 'sub'); - return cp.execFile('powershell', ['-Command', - `[System.IO.Directory]::CreateDirectory("${sub}"); Copy-Item -recurse "${logsPath}" "${sub}"; Compress-Archive -Path "${sub}" -DestinationPath "${outZip}"`], - { cwd: logsPath }, - callback); - default: - return cp.execFile('zip', ['-r', outZip, '.'], { cwd: logsPath }, callback); - } -} diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index e881d6a1e2f3c..be40bfa20d075 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -35,7 +35,6 @@ import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { IDiagnosticsService, DiagnosticsService } from 'vs/platform/diagnostics/electron-main/diagnosticsService'; import { BufferLogService } from 'vs/platform/log/common/bufferLog'; -import { uploadLogs } from 'vs/code/electron-main/logUploader'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IThemeMainService, ThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { Client } from 'vs/base/parts/ipc/common/ipc.net'; @@ -263,7 +262,7 @@ class CodeMain { // Skip this if we are running with --wait where it is expected that we wait for a while. // Also skip when gathering diagnostics (--status) which can take a longer time. let startupWarningDialogHandle: NodeJS.Timeout | undefined = undefined; - if (!environmentService.wait && !environmentService.status && !environmentService.args['upload-logs']) { + if (!environmentService.wait && !environmentService.status) { startupWarningDialogHandle = setTimeout(() => { this.showStartupWarningDialog( localize('secondInstanceNoResponse', "Another instance of {0} is running but not responding", product.nameShort), @@ -285,16 +284,6 @@ class CodeMain { }); } - // Log uploader - if (typeof environmentService.args['upload-logs'] !== 'undefined') { - return instantiationService.invokeFunction(async accessor => { - await uploadLogs(launchClient, accessor.get(IRequestService), environmentService); - - throw new ExpectedError(); - }); - } - - // Windows: allow to set foreground if (platform.isWindows) { await this.windowsAllowSetForegroundWindow(launchClient, logService); @@ -322,13 +311,6 @@ class CodeMain { throw new ExpectedError('Terminating...'); } - // Log uploader usage info - if (typeof environmentService.args['upload-logs'] !== 'undefined') { - logService.warn('Warning: The --upload-logs argument can only be used if Code is already running. Please run it again after Code has started.'); - - throw new ExpectedError('Terminating...'); - } - // dock might be hidden at this case due to a retry if (platform.isMacintosh) { app.dock.show(); diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index e434b71a863a2..45f4ff7d6706a 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -125,7 +125,7 @@ export async function main(argv: string[]): Promise { const processCallbacks: ((child: ChildProcess) => Promise)[] = []; - const verbose = args.verbose || args.status || typeof args['upload-logs'] !== 'undefined'; + const verbose = args.verbose || args.status; if (verbose) { env['ELECTRON_ENABLE_LOGGING'] = '1'; @@ -350,9 +350,7 @@ export async function main(argv: string[]): Promise { env }; - if (typeof args['upload-logs'] !== 'undefined') { - options['stdio'] = ['pipe', 'pipe', 'pipe']; - } else if (!verbose) { + if (!verbose) { options['stdio'] = 'ignore'; } diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 189813daf8ec4..210ac5080a35f 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -64,7 +64,6 @@ export interface ParsedArgs { 'max-memory'?: string; 'file-write'?: boolean; 'file-chmod'?: boolean; - 'upload-logs'?: string; 'driver'?: string; 'driver-verbose'?: boolean; remote?: string; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index b3e99e2b808d3..b53a29f370aac 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -61,7 +61,6 @@ export const options: Option[] = [ { id: 'inspect-extensions', type: 'string', deprecates: 'debugPluginHost', args: 'port', cat: 't', description: localize('inspect-extensions', "Allow debugging and profiling of extensions. Check the developer tools for the connection URI.") }, { id: 'inspect-brk-extensions', type: 'string', deprecates: 'debugBrkPluginHost', args: 'port', cat: 't', description: localize('inspect-brk-extensions', "Allow debugging and profiling of extensions with the extension host being paused after start. Check the developer tools for the connection URI.") }, { id: 'disable-gpu', type: 'boolean', cat: 't', description: localize('disableGPU', "Disable GPU hardware acceleration.") }, - { id: 'upload-logs', type: 'string', cat: 't', description: localize('uploadLogs', "Uploads logs from current session to a secure endpoint.") }, { id: 'max-memory', type: 'string', cat: 't', description: localize('maxMemory', "Max memory size for a window (in Mbytes).") }, { id: 'remote', type: 'string' }, From 03ae3200303ecfffd944c850adac9c6d377d5b68 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 11:30:12 -0700 Subject: [PATCH 193/364] Use localized name for macOS keyboard layout --- package.json | 2 +- .../preferences/browser/keyboardLayoutPicker.ts | 2 +- .../browser/keyboardLayouts/de.darwin.ts | 2 +- .../browser/keyboardLayouts/en-ext.darwin.ts | 2 +- .../browser/keyboardLayouts/en-intl.darwin.ts | 2 +- .../browser/keyboardLayouts/en-uk.darwin.ts | 2 +- .../browser/keyboardLayouts/en.darwin.ts | 16 ++++++++-------- .../browser/keyboardLayouts/es.darwin.ts | 2 +- .../browser/keyboardLayouts/fr.darwin.ts | 2 +- .../browser/keyboardLayouts/it.darwin.ts | 2 +- .../browser/keyboardLayouts/jp-roman.darwin.ts | 2 +- .../browser/keyboardLayouts/jp.darwin.ts | 2 +- .../browser/keyboardLayouts/ko.darwin.ts | 2 +- .../browser/keyboardLayouts/pl.darwin.ts | 2 +- .../browser/keyboardLayouts/ru.darwin.ts | 2 +- .../browser/keyboardLayouts/sv.darwin.ts | 2 +- .../browser/keyboardLayouts/zh-hans.darwin.ts | 2 +- .../services/keybinding/common/keymapService.ts | 9 +++++++++ yarn.lock | 8 ++++---- 19 files changed, 37 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index f897c765b8374..c9fcfda77b221 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "keytar": "4.2.1", "minimist": "1.2.0", "native-is-elevated": "^0.2.1", - "native-keymap": "1.2.5", + "native-keymap": "1.2.6", "native-watchdog": "1.0.0", "node-pty": "0.9.0-beta17", "onigasm-umd": "^2.2.2", diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index aeabf4a637f6b..05b9fb2069fce 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -132,7 +132,7 @@ export class KeyboardLayoutPickerAction extends Action { // Offer to "Auto Detect" const autoDetectMode: IQuickPickItem = { label: nls.localize('autoDetect', "Auto Detect"), - description: isAutoDetect ? `(Current: ${parseKeyboardLayout(currentLayout).label})` : undefined, + description: isAutoDetect ? `Current: ${parseKeyboardLayout(currentLayout).label}` : undefined, picked: isAutoDetect ? true : undefined }; diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts index 573f80946640e..6e870e8c47210 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.German', lang: 'de' }, + { id: 'com.apple.keylayout.German', lang: 'de', localizedName: 'German' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts index 91bc1741acfcc..688281af2beb7 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.USExtended', lang: 'en' }, + { id: 'com.apple.keylayout.USExtended', lang: 'en', localizedName: 'ABC - Extended' }, [], { KeyA: ['a', 'A', '¯', '̄', 4], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts index cdbcf3bcfd2cd..a4f4a9e10b1a0 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.USInternational-PC', lang: 'en' }, + { id: 'com.apple.keylayout.USInternational-PC', lang: 'en', localizedName: 'U.S. International - PC' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts index e50f88303976e..4bebc424b1fcd 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts @@ -8,7 +8,7 @@ import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.British', lang: 'en' }, + { id: 'com.apple.keylayout.British', lang: 'en', localizedName: 'British' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts index fabf23b5864cb..19f435e3c0d49 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts @@ -7,15 +7,15 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.US', lang: 'en' }, + { id: 'com.apple.keylayout.US', lang: 'en', localizedName: 'U.S.' }, [ - { id: 'com.apple.keylayout.ABC', lang: 'en' }, - { id: 'com.sogou.inputmethod.sogou.pinyin', lang: 'zh-Hans' }, - { id: 'com.apple.inputmethod.Kotoeri.Roman', lang: 'en' }, - { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja' }, - { id: 'com.apple.keylayout.Australian', lang: 'en' }, - { id: 'com.apple.keylayout.Canadian', lang: 'en' }, - { id: 'com.apple.keylayout.Brazilian', lang: 'pt' }, + { id: 'com.apple.keylayout.ABC', lang: 'en', localizedName: 'ABC' }, + { id: 'com.sogou.inputmethod.sogou.pinyin', lang: 'zh-Hans', localizedName: 'Pinyin - Simplified' }, + { id: 'com.apple.inputmethod.Kotoeri.Roman', lang: 'en', localizedName: 'Romaji' }, + { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja', localizedName: 'Hiragana' }, + { id: 'com.apple.keylayout.Australian', lang: 'en', localizedName: 'Australian' }, + { id: 'com.apple.keylayout.Canadian', lang: 'en', localizedName: 'Canadian English' }, + { id: 'com.apple.keylayout.Brazilian', lang: 'pt', localizedName: 'Brazilian' }, ], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts index ecc0004d0780b..a7b3986364bc0 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Spanish-ISO', lang: 'es' }, + { id: 'com.apple.keylayout.Spanish-ISO', lang: 'es', localizedName: 'Spanish - ISO' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts index 6b47127cec66f..6bc78c8a2b292 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.French', lang: 'fr' }, + { id: 'com.apple.keylayout.French', lang: 'fr', localizedName: 'French' }, [], { KeyA: ['q', 'Q', '‡', 'Ω', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts index 8cb9dc8f995c8..3d1c557e65ebb 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Italian-Pro', lang: 'it' }, + { id: 'com.apple.keylayout.Italian-Pro', lang: 'it', localizedName: 'Italian' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts index 8f90af0bea967..578a479dc7e83 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.google.inputmethod.Japanese.Roman', lang: 'en' }, + { id: 'com.google.inputmethod.Japanese.Roman', lang: 'en', localizedName: 'Alphanumeric (Google)' }, [], { KeyA: ['a', 'A', '¯', '̄', 4], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts index a48e202b4fb81..1835862116e5f 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja' }, + { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja', localizedName: 'Hiragana' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts index d79920103d62a..e767bd03dcd0c 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts @@ -8,7 +8,7 @@ import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.inputmethod.Korean.2SetKorean', lang: 'ko' }, + { id: 'com.apple.inputmethod.Korean.2SetKorean', lang: 'ko', localizedName: '2-Set Korean' }, [], { KeyA: ['ㅁ', 'ㅁ', 'a', 'A', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts index 75bac351170c7..8ae036710a2f0 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.PolishPro', lang: 'pl' }, + { id: 'com.apple.keylayout.PolishPro', lang: 'pl', localizedName: 'Polish - Pro' }, [], { KeyA: ['a', 'A', 'ą', 'Ą', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts index afecb02810dec..9140df78e5c5d 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Russian', lang: 'ru' }, + { id: 'com.apple.keylayout.Russian', lang: 'ru', localizedName: 'Russian' }, [], { KeyA: ['ф', 'Ф', 'ƒ', 'ƒ', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts index e5b57ab30a3c7..2c5f6f3e582b0 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Swedish-Pro', lang: 'sv' }, + { id: 'com.apple.keylayout.Swedish-Pro', lang: 'sv', localizedName: 'Swedish - Pro' }, [], { KeyA: ['a', 'A', '', '◊', 0], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts index cf8bfbf0ac67b..df8e9252fa6f1 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.inputmethod.SCIM.ITABC', lang: 'zh-Hans' }, + { id: 'com.apple.inputmethod.SCIM.ITABC', lang: 'zh-Hans', localizedName: '搜狗拼音' }, [], { KeyA: ['a', 'A', 'å', 'Å', 0], diff --git a/src/vs/workbench/services/keybinding/common/keymapService.ts b/src/vs/workbench/services/keybinding/common/keymapService.ts index f70f8f20bc827..c9d5dbd91153b 100644 --- a/src/vs/workbench/services/keybinding/common/keymapService.ts +++ b/src/vs/workbench/services/keybinding/common/keymapService.ts @@ -78,11 +78,13 @@ export interface ILinuxKeyboardLayoutInfo { "IKeyboardLayoutInfo" : { "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "lang": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + "localizedName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ export interface IMacKeyboardLayoutInfo { id: string; lang: string; + localizedName?: string; } export type IKeyboardLayoutInfo = IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo; @@ -137,6 +139,13 @@ export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label if ((layout).id) { let macLayout = layout; + if (macLayout.localizedName) { + return { + label: macLayout.localizedName, + description: '' + }; + } + if (/^com\.apple\.keylayout\./.test(macLayout.id)) { return { label: macLayout.id.replace(/^com\.apple\.keylayout\./, '').replace(/-/, ' '), diff --git a/yarn.lock b/yarn.lock index 107c1f0fd3766..acd186d7f7e26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5951,10 +5951,10 @@ native-is-elevated@^0.2.1: resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.2.1.tgz#70a2123a8575b9f624a3ef465d98cb74ae017385" integrity sha1-cKISOoV1ufYko+9GXZjLdK4Bc4U= -native-keymap@1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-1.2.5.tgz#1035a9417b9a9340cf8097763a43c76d588165a5" - integrity sha1-EDWpQXuak0DPgJd2OkPHbViBZaU= +native-keymap@1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-1.2.6.tgz#93d1b4c4ae0e9136bc14538cafe02c0bbe95bebf" + integrity sha512-8hEr6wNkb7OmGPFLFk1cAsnOt2Y3F4mtBffr8uOyX0kKOjr2JVetSt9TKjk0xyJw/B/HcEgMhXmjFKzGN+9JjA== native-watchdog@1.0.0: version "1.0.0" From 5a5ccf7ec13f01228d4d607983e3d2efbc81fb3b Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 20 Jun 2019 18:51:55 +0000 Subject: [PATCH 194/364] fixes #75856 --- src/vs/workbench/workbench.main.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index a6c31adbe640c..b1130436d6dbb 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -71,8 +71,6 @@ import { IRequestService } from 'vs/platform/request/node/request'; import { RequestService } from 'vs/platform/request/electron-browser/requestService'; import { LifecycleService } from 'vs/platform/lifecycle/electron-browser/lifecycleService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; -import { DialogService } from 'vs/platform/dialogs/browser/dialogService'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; @@ -138,7 +136,6 @@ import 'vs/workbench/services/window/electron-browser/windowService'; import 'vs/workbench/services/telemetry/electron-browser/telemetryService'; import 'vs/workbench/services/configurationResolver/electron-browser/configurationResolverService'; -registerSingleton(IDialogService, DialogService, true); registerSingleton(IMenuService, MenuService, true); registerSingleton(IListService, ListService, true); registerSingleton(IOpenerService, OpenerService, true); From 8c0059a9ca9bfacfc81bbcd73d213574ab83c438 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 11:57:24 -0700 Subject: [PATCH 195/364] User keyboard layout --- .../preferences/browser/keyboardLayoutPicker.ts | 4 +++- .../workbench/services/keybinding/common/keymapInfo.ts | 10 ++++++---- .../services/keybinding/common/keymapService.ts | 6 ++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 05b9fb2069fce..b3f01695c0d9c 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -113,11 +113,13 @@ export class KeyboardLayoutPickerAction extends Action { const picked = !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout); const layoutInfo = parseKeyboardLayout(layout); return { - label: layoutInfo.label, + label: [layoutInfo.label, (layout && layout.isUserKeyboardLayout) ? '(User configured layout)' : ''].join(' '), id: (layout).text || (layout).lang || (layout).layout, description: layoutInfo.description + (picked ? ' (Current layout)' : ''), picked: !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout) }; + }).sort((a: IQuickPickItem, b: IQuickPickItem) => { + return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0); }); if (picks.length > 0) { diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index 7d2665d006d97..3bd488a3d66f9 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -47,7 +47,7 @@ function deserializeMapping(serializedMapping: ISerializedMapping) { return ret; } -interface IKeyboardMapping { +interface IRawMixedKeyboardMapping { [key: string]: { value: string, withShift: string; @@ -66,15 +66,16 @@ interface ISerializedMapping { } export class KeymapInfo { - mapping: IKeyboardMapping; + mapping: IRawMixedKeyboardMapping; isUserKeyboardLayout: boolean; constructor(public layout: IKeyboardLayoutInfo, public secondaryLayouts: IKeyboardLayoutInfo[], keyboardMapping: ISerializedMapping, isUserKeyboardLayout?: boolean) { this.mapping = deserializeMapping(keyboardMapping); this.isUserKeyboardLayout = !!isUserKeyboardLayout; + this.layout.isUserKeyboardLayout = !!isUserKeyboardLayout; } - static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IKeyboardMapping, isUserKeyboardLayout?: boolean): KeymapInfo { + static createKeyboardLayoutFromDebugInfo(layout: IKeyboardLayoutInfo, value: IRawMixedKeyboardMapping, isUserKeyboardLayout?: boolean): KeymapInfo { let keyboardLayoutInfo = new KeymapInfo(layout, [], {}, true); keyboardLayoutInfo.mapping = value; return keyboardLayoutInfo; @@ -85,9 +86,10 @@ export class KeymapInfo { this.secondaryLayouts = other.secondaryLayouts; this.mapping = other.mapping; this.isUserKeyboardLayout = other.isUserKeyboardLayout; + this.layout.isUserKeyboardLayout = other.isUserKeyboardLayout; } - fuzzyEqual(other: IKeyboardMapping): boolean { + fuzzyEqual(other: IRawMixedKeyboardMapping): boolean { for (let key in other) { if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { // keymap from Chromium is probably wrong. diff --git a/src/vs/workbench/services/keybinding/common/keymapService.ts b/src/vs/workbench/services/keybinding/common/keymapService.ts index c9d5dbd91153b..44258163415c8 100644 --- a/src/vs/workbench/services/keybinding/common/keymapService.ts +++ b/src/vs/workbench/services/keybinding/common/keymapService.ts @@ -87,7 +87,7 @@ export interface IMacKeyboardLayoutInfo { localizedName?: string; } -export type IKeyboardLayoutInfo = IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo; +export type IKeyboardLayoutInfo = (IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo) & { isUserKeyboardLayout?: boolean; }; export const IKeymapService = createDecorator('keymapService'); @@ -126,7 +126,9 @@ export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeybo } export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { - + if (!layout) { + return { label: '', description: '' }; + } if ((layout).name) { // windows From ea6151f952ff0aa172191e7e4627add315e1f645 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 12:00:36 -0700 Subject: [PATCH 196/364] simplify common keymap layer --- .../browser/keyboardLayoutPicker.ts | 2 +- .../keybinding/browser/keybindingService.ts | 2 +- .../keybinding/browser/keymapService.ts | 3 +- .../services/keybinding/common/keymapInfo.ts | 173 ++++++++++++++++- .../keybinding/common/keymapService.ts | 176 ------------------ .../electron-browser/nativeKeymapService.ts | 2 +- 6 files changed, 176 insertions(+), 182 deletions(-) delete mode 100644 src/vs/workbench/services/keybinding/common/keymapService.ts diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index b3f01695c0d9c..46410fc9cd0e3 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, areKeyboardLayoutsEqual, parseKeyboardLayout } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService, areKeyboardLayoutsEqual, parseKeyboardLayout } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; diff --git a/src/vs/workbench/services/keybinding/browser/keybindingService.ts b/src/vs/workbench/services/keybinding/browser/keybindingService.ts index a47e25c4e7d16..fb7e5465845d2 100644 --- a/src/vs/workbench/services/keybinding/browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/browser/keybindingService.ts @@ -43,7 +43,7 @@ import { IFileService, FileChangesEvent, FileChangeType } from 'vs/platform/file import { dirname, isEqual } from 'vs/base/common/resources'; import { parse } from 'vs/base/common/json'; import * as objects from 'vs/base/common/objects'; -import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { getDispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { isArray } from 'vs/base/common/types'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 12cae6abfaeff..126e5ec17dd66 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, toDisposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, IWindowsKeyboardLayoutInfo, IMacKeyboardLayoutInfo, ILinuxKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, IWindowsKeyboardLayoutInfo, IMacKeyboardLayoutInfo, ILinuxKeyboardLayoutInfo, KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; @@ -28,7 +28,6 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; export class BrowserKeyboardMapperFactory { public static readonly INSTANCE = new BrowserKeyboardMapperFactory(); diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index 3bd488a3d66f9..9e281fb607200 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -3,8 +3,179 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapService'; +import { Event } from 'vs/base/common/event'; import { isWindows } from 'vs/base/common/platform'; +import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; +import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; +import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; + + +export interface IWindowsKeyMapping { + vkey: string; + value: string; + withShift: string; + withAltGr: string; + withShiftAltGr: string; +} +export interface IWindowsKeyboardMapping { + [code: string]: IWindowsKeyMapping; +} +export interface ILinuxKeyMapping { + value: string; + withShift: string; + withAltGr: string; + withShiftAltGr: string; +} +export interface ILinuxKeyboardMapping { + [code: string]: ILinuxKeyMapping; +} +export interface IMacKeyMapping { + value: string; + withShift: string; + withAltGr: string; + withShiftAltGr: string; + valueIsDeadKey: boolean; + withShiftIsDeadKey: boolean; + withAltGrIsDeadKey: boolean; + withShiftAltGrIsDeadKey: boolean; +} +export interface IMacKeyboardMapping { + [code: string]: IMacKeyMapping; +} + +export type IKeyboardMapping = IWindowsKeyboardMapping | ILinuxKeyboardMapping | IMacKeyboardMapping; + +/* __GDPR__FRAGMENT__ + "IKeyboardLayoutInfo" : { + "name" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "id": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "text": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } +*/ +export interface IWindowsKeyboardLayoutInfo { + name: string; + id: string; + text: string; +} + +/* __GDPR__FRAGMENT__ + "IKeyboardLayoutInfo" : { + "model" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "layout": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "variant": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "options": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "rules": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } +*/ +export interface ILinuxKeyboardLayoutInfo { + model: string; + layout: string; + variant: string; + options: string; + rules: string; +} + +/* __GDPR__FRAGMENT__ + "IKeyboardLayoutInfo" : { + "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "lang": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + "localizedName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } +*/ +export interface IMacKeyboardLayoutInfo { + id: string; + lang: string; + localizedName?: string; +} + +export type IKeyboardLayoutInfo = (IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo) & { isUserKeyboardLayout?: boolean; }; + +export const IKeymapService = createDecorator('keymapService'); + +export interface IKeymapService { + _serviceBrand: ServiceIdentifier; + onDidChangeKeyboardMapper: Event; + getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper; + getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null; + getAllKeyboardLayouts(): IKeyboardLayoutInfo[]; + getRawKeyboardMapping(): IKeyboardMapping | null; + validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void; +} + +export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeyboardLayoutInfo | null): boolean { + if (!a || !b) { + return false; + } + + if ((a).name && (b).name && (a).name === (b).name) { + return true; + } + + if ((a).id && (b).id && (a).id === (b).id) { + return true; + } + + if ((a).model && + (b).model && + (a).model === (b).model && + (a).layout === (b).layout + ) { + return true; + } + + return false; +} + +export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { + if (!layout) { + return { label: '', description: '' }; + } + + if ((layout).name) { + // windows + let windowsLayout = layout; + return { + label: windowsLayout.text, + description: '' + }; + } + + if ((layout).id) { + let macLayout = layout; + if (macLayout.localizedName) { + return { + label: macLayout.localizedName, + description: '' + }; + } + + if (/^com\.apple\.keylayout\./.test(macLayout.id)) { + return { + label: macLayout.id.replace(/^com\.apple\.keylayout\./, '').replace(/-/, ' '), + description: '' + }; + } + if (/^.*inputmethod\./.test(macLayout.id)) { + return { + label: macLayout.id.replace(/^.*inputmethod\./, '').replace(/[-\.]/, ' '), + description: `Input Method (${macLayout.lang})` + }; + } + + return { + label: macLayout.lang, + description: '' + }; + } + + let linuxLayout = layout; + + return { + label: linuxLayout.layout, + description: '' + }; +} function deserializeMapping(serializedMapping: ISerializedMapping) { let mapping = serializedMapping; diff --git a/src/vs/workbench/services/keybinding/common/keymapService.ts b/src/vs/workbench/services/keybinding/common/keymapService.ts deleted file mode 100644 index 44258163415c8..0000000000000 --- a/src/vs/workbench/services/keybinding/common/keymapService.ts +++ /dev/null @@ -1,176 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event } from 'vs/base/common/event'; -import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; -import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; -import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; -import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; - -export interface IWindowsKeyMapping { - vkey: string; - value: string; - withShift: string; - withAltGr: string; - withShiftAltGr: string; -} -export interface IWindowsKeyboardMapping { - [code: string]: IWindowsKeyMapping; -} -export interface ILinuxKeyMapping { - value: string; - withShift: string; - withAltGr: string; - withShiftAltGr: string; -} -export interface ILinuxKeyboardMapping { - [code: string]: ILinuxKeyMapping; -} -export interface IMacKeyMapping { - value: string; - withShift: string; - withAltGr: string; - withShiftAltGr: string; - valueIsDeadKey: boolean; - withShiftIsDeadKey: boolean; - withAltGrIsDeadKey: boolean; - withShiftAltGrIsDeadKey: boolean; -} -export interface IMacKeyboardMapping { - [code: string]: IMacKeyMapping; -} - -export type IKeyboardMapping = IWindowsKeyboardMapping | ILinuxKeyboardMapping | IMacKeyboardMapping; - -/* __GDPR__FRAGMENT__ - "IKeyboardLayoutInfo" : { - "name" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "id": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "text": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } -*/ -export interface IWindowsKeyboardLayoutInfo { - name: string; - id: string; - text: string; -} - -/* __GDPR__FRAGMENT__ - "IKeyboardLayoutInfo" : { - "model" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "layout": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "variant": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "options": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "rules": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } -*/ -export interface ILinuxKeyboardLayoutInfo { - model: string; - layout: string; - variant: string; - options: string; - rules: string; -} - -/* __GDPR__FRAGMENT__ - "IKeyboardLayoutInfo" : { - "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "lang": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - "localizedName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } - } -*/ -export interface IMacKeyboardLayoutInfo { - id: string; - lang: string; - localizedName?: string; -} - -export type IKeyboardLayoutInfo = (IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo) & { isUserKeyboardLayout?: boolean; }; - -export const IKeymapService = createDecorator('keymapService'); - -export interface IKeymapService { - _serviceBrand: ServiceIdentifier; - onDidChangeKeyboardMapper: Event; - getKeyboardMapper(dispatchConfig: DispatchConfig): IKeyboardMapper; - getCurrentKeyboardLayout(): IKeyboardLayoutInfo | null; - getAllKeyboardLayouts(): IKeyboardLayoutInfo[]; - getRawKeyboardMapping(): IKeyboardMapping | null; - validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void; -} - -export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeyboardLayoutInfo | null): boolean { - if (!a || !b) { - return false; - } - - if ((a).name && (b).name && (a).name === (b).name) { - return true; - } - - if ((a).id && (b).id && (a).id === (b).id) { - return true; - } - - if ((a).model && - (b).model && - (a).model === (b).model && - (a).layout === (b).layout - ) { - return true; - } - - return false; -} - -export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { - if (!layout) { - return { label: '', description: '' }; - } - - if ((layout).name) { - // windows - let windowsLayout = layout; - return { - label: windowsLayout.text, - description: '' - }; - } - - if ((layout).id) { - let macLayout = layout; - if (macLayout.localizedName) { - return { - label: macLayout.localizedName, - description: '' - }; - } - - if (/^com\.apple\.keylayout\./.test(macLayout.id)) { - return { - label: macLayout.id.replace(/^com\.apple\.keylayout\./, '').replace(/-/, ' '), - description: '' - }; - } - if (/^.*inputmethod\./.test(macLayout.id)) { - return { - label: macLayout.id.replace(/^.*inputmethod\./, '').replace(/[-\.]/, ' '), - description: `Input Method (${macLayout.lang})` - }; - } - - return { - label: macLayout.lang, - description: '' - }; - } - - let linuxLayout = layout; - - return { - label: linuxLayout.layout, - description: '' - }; -} \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts b/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts index 85f0fa91c8a92..475c881af9fad 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/nativeKeymapService.ts @@ -5,7 +5,7 @@ import * as nativeKeymap from 'native-keymap'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping } from 'vs/workbench/services/keybinding/common/keymapService'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; import { Emitter, Event } from 'vs/base/common/event'; From 27c4fdd645a0902ae72b9f81082d5ca5fe1525e9 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 12:10:11 -0700 Subject: [PATCH 197/364] load user keyboard layout after initialization --- .../services/keybinding/browser/keymapService.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 126e5ec17dd66..b935e3ad7c3d5 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -544,11 +544,11 @@ class BrowserKeymapService extends Disposable implements IKeymapService { })); this._userKeyboardLayout = new UserKeyboardLayout(environmentService.keyboardLayoutResource, fileService); - this._userKeyboardLayout.initialize(); - - if (this._userKeyboardLayout.keyboardLayout) { - BrowserKeyboardMapperFactory.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); - } + this._userKeyboardLayout.initialize().then(() => { + if (this._userKeyboardLayout.keyboardLayout) { + BrowserKeyboardMapperFactory.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + } + }); this._register(this._userKeyboardLayout.onDidChange(() => { let userKeyboardLayouts = BrowserKeyboardMapperFactory.INSTANCE.keymapInfos.filter(layout => layout.isUserKeyboardLayout); From 1b78a8869c94f3b91b7bc4d13c0fad036ab3a7cf Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 12:32:47 -0700 Subject: [PATCH 198/364] US Standard keyboard info --- .../browser/keyboardLayouts/en.darwin.ts | 2 +- .../browser/keyboardLayouts/en.linux.ts | 2 +- .../browser/keyboardLayouts/en.win.ts | 2 +- .../keybinding/browser/keymapService.ts | 35 +++++++++++++------ .../services/keybinding/common/keymapInfo.ts | 4 +-- 5 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts index 19f435e3c0d49..ee78fd8254dbf 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.US', lang: 'en', localizedName: 'U.S.' }, + { id: 'com.apple.keylayout.US', lang: 'en', localizedName: 'U.S.', isUSStandard: true }, [ { id: 'com.apple.keylayout.ABC', lang: 'en', localizedName: 'ABC' }, { id: 'com.sogou.inputmethod.sogou.pinyin', lang: 'zh-Hans', localizedName: 'Pinyin - Simplified' }, diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts index ae5e356006add..1ea1d427390b1 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { model: 'pc105', layout: 'us', variant: '', options: '', rules: 'evdev' }, + { model: 'pc105', layout: 'us', variant: '', options: '', rules: 'evdev', isUSStandard: true }, [ { model: 'pc105', layout: 'cn', variant: '', options: '', rules: 'evdev' }, ], diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts index cb7e8e42da293..be1ca6ff8b84a 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts @@ -7,7 +7,7 @@ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/bro import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000409', id: '', text: 'US' }, + { name: '00000409', id: '', text: 'US', isUSStandard: true }, [ { name: '00000804', id: '', text: 'Chinese (Simplified) - US Keyboard' }, { name: '00000411', id: '', text: 'Japanese' }, diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index b935e3ad7c3d5..ac0aa22aa4c33 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, toDisposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, IWindowsKeyboardLayoutInfo, IMacKeyboardLayoutInfo, ILinuxKeyboardLayoutInfo, KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, IWindowsKeyboardLayoutInfo, IMacKeyboardLayoutInfo, ILinuxKeyboardLayoutInfo, KeymapInfo, IRawMixedKeyboardMapping } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; @@ -85,7 +85,7 @@ export class BrowserKeyboardMapperFactory { if ((navigator).keyboard && (navigator).keyboard.addEventListener) { (navigator).keyboard.addEventListener!('layoutchange', () => { // Update user keyboard map settings - this._getBrowserKeyMapping().then((mapping: IKeyboardMapping) => { + this._getBrowserKeyMapping().then((mapping: IKeyboardMapping | null) => { if (this.isKeyMappingActive(mapping)) { return; } @@ -108,7 +108,11 @@ export class BrowserKeyboardMapperFactory { this._keymapInfos.splice(index, 1); } - getMatchedKeymapInfo(keyMapping: IKeyboardMapping): KeymapInfo | null { + getMatchedKeymapInfo(keyMapping: IKeyboardMapping | null): KeymapInfo | null { + if (!keyMapping) { + return null; + } + for (let i = 0; i < this._mru.length; i++) { if (this._mru[i].fuzzyEqual(keyMapping)) { return this._mru[i]; @@ -118,12 +122,22 @@ export class BrowserKeyboardMapperFactory { return null; } - isKeyMappingActive(keymap: IKeyboardMapping) { - return this._activeKeymapInfo && this._activeKeymapInfo.fuzzyEqual(keymap); + getUSStandardLayout() { + const usStandardLayouts = this._mru.filter(layout => layout.layout.isUSStandard); + + if (usStandardLayouts.length) { + return usStandardLayouts[0]; + } + + return null; + } + + isKeyMappingActive(keymap: IKeyboardMapping | null) { + return this._activeKeymapInfo && keymap && this._activeKeymapInfo.fuzzyEqual(keymap); } - setActiveKeyMapping(keymap: IKeyboardMapping) { - this._activeKeymapInfo = this.getMatchedKeymapInfo(keymap); + setActiveKeyMapping(keymap: IKeyboardMapping | null) { + this._activeKeymapInfo = this.getMatchedKeymapInfo(keymap) || this.getUSStandardLayout(); if (!this._activeKeymapInfo) { return; @@ -179,7 +193,6 @@ export class BrowserKeyboardMapperFactory { return new MacLinuxFallbackKeyboardMapper(OS); } return this._keyboardMapper!; - } public validateCurrentKeyboardMapping(keyboardEvent: IKeyboardEvent): void { @@ -307,7 +320,7 @@ export class BrowserKeyboardMapperFactory { return true; } - private async _getBrowserKeyMapping() { + private async _getBrowserKeyMapping(): Promise { if ((navigator as any).keyboard) { try { return (navigator as any).keyboard.getLayoutMap().then((e: any) => { @@ -327,14 +340,14 @@ export class BrowserKeyboardMapperFactory { return matchedKeyboardLayout.mapping; } - return {}; + return null; }); } catch { // getLayoutMap can throw if invoked from a nested browsing context } } - return {}; + return null; } //#endregion diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index 9e281fb607200..fa3803bfd1b7e 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -89,7 +89,7 @@ export interface IMacKeyboardLayoutInfo { localizedName?: string; } -export type IKeyboardLayoutInfo = (IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo) & { isUserKeyboardLayout?: boolean; }; +export type IKeyboardLayoutInfo = (IWindowsKeyboardLayoutInfo | ILinuxKeyboardLayoutInfo | IMacKeyboardLayoutInfo) & { isUserKeyboardLayout?: boolean; isUSStandard?: true }; export const IKeymapService = createDecorator('keymapService'); @@ -218,7 +218,7 @@ function deserializeMapping(serializedMapping: ISerializedMapping) { return ret; } -interface IRawMixedKeyboardMapping { +export interface IRawMixedKeyboardMapping { [key: string]: { value: string, withShift: string; From 2e65c0b4a7876e9a1a91dfe1083368eddb244a07 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 12:53:11 -0700 Subject: [PATCH 199/364] better score for layout --- .../keybinding/browser/keymapService.ts | 94 ++++--------------- .../services/keybinding/common/keymapInfo.ts | 22 +++++ 2 files changed, 42 insertions(+), 74 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index ac0aa22aa4c33..1917e87146f81 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -113,6 +113,22 @@ export class BrowserKeyboardMapperFactory { return null; } + let usStandard = this.getUSStandardLayout(); + + if (usStandard) { + let maxScore = usStandard.getScore(keyMapping); + let result = usStandard; + for (let i = 0; i < this._mru.length; i++) { + let score = this._mru[i].getScore(keyMapping); + if (score > maxScore) { + maxScore = score; + result = this._mru[i]; + } + } + + return result; + } + for (let i = 0; i < this._mru.length; i++) { if (this._mru[i].fuzzyEqual(keyMapping)) { return this._mru[i]; @@ -234,26 +250,13 @@ export class BrowserKeyboardMapperFactory { private _setKeyboardData(keymapInfo: KeymapInfo): void { this._initialized = true; - this._keyboardMapper = new CachedKeyboardMapper(BrowserKeyboardMapperFactory._createKeyboardMapper(keymapInfo.mapping)); + this._keyboardMapper = new CachedKeyboardMapper(BrowserKeyboardMapperFactory._createKeyboardMapper(keymapInfo)); this._onDidChangeKeyboardMapper.fire(); } - private static _isUSStandard(rawMapping: IKeyboardMapping): boolean { - for (let key in rawMapping) { - let str = rawMapping[key].value; - let keyCode = KeyCodeUtils.fromString(str); - let usKeyCode = US_SCANCODE_MAP[key]; - - if (keyCode !== usKeyCode) { - return false; - } - - } - return true; - } - - private static _createKeyboardMapper(rawMapping: IKeyboardMapping): IKeyboardMapper { - const isUSStandard = BrowserKeyboardMapperFactory._isUSStandard(rawMapping); + private static _createKeyboardMapper(keymapInfo: KeymapInfo): IKeyboardMapper { + let rawMapping = keymapInfo.mapping; + const isUSStandard = !!keymapInfo.layout.isUSStandard; if (OS === OperatingSystem.Windows) { return new WindowsKeyboardMapper(isUSStandard, rawMapping); } @@ -353,63 +356,6 @@ export class BrowserKeyboardMapperFactory { //#endregion } -export const US_SCANCODE_MAP: { [str: string]: KeyCode; } = {}; - -(function () { - function define(scanCode: string, keyCode: KeyCode): void { - US_SCANCODE_MAP[scanCode] = keyCode; - } - - define('Backquote', KeyCode.US_BACKTICK); - define('Backslash', KeyCode.US_BACKSLASH); - define('BracketLeft', KeyCode.US_OPEN_SQUARE_BRACKET); - define('BracketRight', KeyCode.US_CLOSE_SQUARE_BRACKET); - define('Comma', KeyCode.US_COMMA); - define('Digit0', KeyCode.KEY_0); - define('Digit1', KeyCode.KEY_1); - define('Digit2', KeyCode.KEY_2); - define('Digit3', KeyCode.KEY_3); - define('Digit4', KeyCode.KEY_4); - define('Digit5', KeyCode.KEY_5); - define('Digit6', KeyCode.KEY_6); - define('Digit7', KeyCode.KEY_7); - define('Digit8', KeyCode.KEY_8); - define('Digit9', KeyCode.KEY_9); - define('Equal', KeyCode.US_EQUAL); - define('IntlBackslash', KeyCode.Unknown); - define('KeyA', KeyCode.KEY_A); - define('KeyB', KeyCode.KEY_B); - define('KeyC', KeyCode.KEY_C); - define('KeyD', KeyCode.KEY_D); - define('KeyE', KeyCode.KEY_E); - define('KeyF', KeyCode.KEY_F); - define('KeyG', KeyCode.KEY_G); - define('KeyH', KeyCode.KEY_H); - define('KeyI', KeyCode.KEY_I); - define('KeyJ', KeyCode.KEY_J); - define('KeyK', KeyCode.KEY_K); - define('KeyL', KeyCode.KEY_L); - define('KeyM', KeyCode.KEY_M); - define('KeyN', KeyCode.KEY_N); - define('KeyO', KeyCode.KEY_O); - define('KeyP', KeyCode.KEY_P); - define('KeyQ', KeyCode.KEY_Q); - define('KeyR', KeyCode.KEY_R); - define('KeyS', KeyCode.KEY_S); - define('KeyT', KeyCode.KEY_T); - define('KeyU', KeyCode.KEY_U); - define('KeyV', KeyCode.KEY_V); - define('KeyW', KeyCode.KEY_W); - define('KeyX', KeyCode.KEY_X); - define('KeyY', KeyCode.KEY_Y); - define('KeyZ', KeyCode.KEY_Z); - define('Minus', KeyCode.US_MINUS); - define('Period', KeyCode.US_DOT); - define('Quote', KeyCode.US_QUOTE); - define('Semicolon', KeyCode.US_SEMICOLON); - define('Slash', KeyCode.US_SLASH); -})(); - class UserKeyboardLayout extends Disposable { private readonly reloadConfigurationScheduler: RunOnceScheduler; protected readonly _onDidChange: Emitter = this._register(new Emitter()); diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index fa3803bfd1b7e..6edaa141dc095 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -260,6 +260,28 @@ export class KeymapInfo { this.layout.isUserKeyboardLayout = other.isUserKeyboardLayout; } + getScore(other: IRawMixedKeyboardMapping): number { + let score = 0; + for (let key in other) { + if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { + // keymap from Chromium is probably wrong. + continue; + } + if (this.mapping[key] === undefined) { + score -= 1; + } + + let currentMapping = this.mapping[key]; + let otherMapping = other[key]; + + if (currentMapping.value !== otherMapping.value) { + score -= 1; + } + } + + return score; + } + fuzzyEqual(other: IRawMixedKeyboardMapping): boolean { for (let key in other) { if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { From 65a01566655c9ae954ff0d22d0c1d11a51ef209b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 12:55:11 -0700 Subject: [PATCH 200/364] fast return keyboard layout if 48-keymap matches --- .../services/keybinding/browser/keymapService.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 1917e87146f81..dd04ed81ec814 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -117,10 +117,18 @@ export class BrowserKeyboardMapperFactory { if (usStandard) { let maxScore = usStandard.getScore(keyMapping); + if (maxScore === 0) { + return usStandard; + } + let result = usStandard; for (let i = 0; i < this._mru.length; i++) { let score = this._mru[i].getScore(keyMapping); if (score > maxScore) { + if (score === 0) { + return this._mru[i]; + } + maxScore = score; result = this._mru[i]; } From 9e5594900386b0c35441127bfc55aa6878040171 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 13:23:05 -0700 Subject: [PATCH 201/364] a single keyboard event can be a keymap --- .../keybinding/browser/keymapService.ts | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index dd04ed81ec814..59acadfcd3e66 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -14,7 +14,6 @@ import { OS, OperatingSystem, isMacintosh, isWindows, isLinux } from 'vs/base/co import { WindowsKeyboardMapper } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; -import { KeyCodeUtils, KeyCode } from 'vs/base/common/keyCodes'; import { IMacLinuxKeyboardMapping, MacLinuxKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxKeyboardMapper'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { URI } from 'vs/base/common/uri'; @@ -194,12 +193,12 @@ export class BrowserKeyboardMapperFactory { this._updateKeyboardLayoutAsync(this._initialized); } - private _updateKeyboardLayoutAsync(initialized: boolean) { + private _updateKeyboardLayoutAsync(initialized: boolean, keyboardEvent?: IKeyboardEvent) { if (!initialized) { return; } - this._getBrowserKeyMapping().then(keyMap => { + this._getBrowserKeyMapping(keyboardEvent).then(keyMap => { // might be false positive if (this.isKeyMappingActive(keyMap)) { return; @@ -230,7 +229,7 @@ export class BrowserKeyboardMapperFactory { return; } - this._updateKeyboardLayoutAsync(true); + this._updateKeyboardLayoutAsync(true, keyboardEvent); } public setKeyboardLayout(layoutName: string) { @@ -331,7 +330,7 @@ export class BrowserKeyboardMapperFactory { return true; } - private async _getBrowserKeyMapping(): Promise { + private async _getBrowserKeyMapping(keyboardEvent?: IKeyboardEvent): Promise { if ((navigator as any).keyboard) { try { return (navigator as any).keyboard.getLayoutMap().then((e: any) => { @@ -356,6 +355,23 @@ export class BrowserKeyboardMapperFactory { } catch { // getLayoutMap can throw if invoked from a nested browsing context } + } else if (keyboardEvent && !keyboardEvent.shiftKey && !keyboardEvent.altKey && !keyboardEvent.metaKey && !keyboardEvent.metaKey) { + let ret: IKeyboardMapping = {}; + const standardKeyboardEvent = keyboardEvent as StandardKeyboardEvent; + ret[standardKeyboardEvent.browserEvent.code] = { + 'value': standardKeyboardEvent.browserEvent.key, + 'withShift': '', + 'withAltGr': '', + 'withShiftAltGr': '' + }; + + const matchedKeyboardLayout = this.getMatchedKeymapInfo(ret); + + if (matchedKeyboardLayout) { + return matchedKeyboardLayout.mapping; + } + + return null; } return null; From f4b6f17ca3e7d16aee41e22144ef3566fbdd3076 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 15:01:56 -0700 Subject: [PATCH 202/364] switch to user selected keyboard layout --- .../browser/keyboardLayoutPicker.ts | 16 ++++--- .../keybinding/browser/keymapService.ts | 44 +++++++++++-------- .../services/keybinding/common/keymapInfo.ts | 26 ++++++++++- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 46410fc9cd0e3..35ea30c421908 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, areKeyboardLayoutsEqual, parseKeyboardLayout } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { IKeymapService, areKeyboardLayoutsEqual, parseKeyboardLayoutDescription, getKeyboardLayoutId, IKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; @@ -34,7 +34,7 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor let layout = this.keymapService.getCurrentKeyboardLayout(); if (layout) { - let layoutInfo = parseKeyboardLayout(layout); + let layoutInfo = parseKeyboardLayoutDescription(layout); this.pickerElement.value = this.statusbarService.addEntry( { text: `Layout: ${layoutInfo.label}`, @@ -49,7 +49,7 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor this._register(keymapService.onDidChangeKeyboardMapper(() => { let layout = this.keymapService.getCurrentKeyboardLayout(); - let layoutInfo = parseKeyboardLayout(layout); + let layoutInfo = parseKeyboardLayoutDescription(layout); if (this.pickerElement.value) { this.pickerElement.value.update({ @@ -75,6 +75,9 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor const workbenchContributionsRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(KeyboardLayoutPickerContribution, LifecyclePhase.Starting); +interface LayoutQuickPickItem extends IQuickPickItem { + layout: IKeyboardLayoutInfo; +} export class KeyboardLayoutPickerAction extends Action { static readonly ID = KEYBOARD_LAYOUT_OPEN_PICKER; @@ -111,8 +114,9 @@ export class KeyboardLayoutPickerAction extends Action { const picks: QuickPickInput[] = layouts.map(layout => { const picked = !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout); - const layoutInfo = parseKeyboardLayout(layout); + const layoutInfo = parseKeyboardLayoutDescription(layout); return { + layout: layout, label: [layoutInfo.label, (layout && layout.isUserKeyboardLayout) ? '(User configured layout)' : ''].join(' '), id: (layout).text || (layout).lang || (layout).layout, description: layoutInfo.description + (picked ? ' (Current layout)' : ''), @@ -134,7 +138,7 @@ export class KeyboardLayoutPickerAction extends Action { // Offer to "Auto Detect" const autoDetectMode: IQuickPickItem = { label: nls.localize('autoDetect', "Auto Detect"), - description: isAutoDetect ? `Current: ${parseKeyboardLayout(currentLayout).label}` : undefined, + description: isAutoDetect ? `Current: ${parseKeyboardLayoutDescription(currentLayout).label}` : undefined, picked: isAutoDetect ? true : undefined }; @@ -171,7 +175,7 @@ export class KeyboardLayoutPickerAction extends Action { return Promise.resolve(); } - this.configurationService.updateValue('keyboard.layout', pick.label); + this.configurationService.updateValue('keyboard.layout', getKeyboardLayoutId((pick).layout)); } } diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 59acadfcd3e66..83c78cc166461 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -6,11 +6,11 @@ import * as nls from 'vs/nls'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, toDisposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, IWindowsKeyboardLayoutInfo, IMacKeyboardLayoutInfo, ILinuxKeyboardLayoutInfo, KeymapInfo, IRawMixedKeyboardMapping } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, KeymapInfo, IRawMixedKeyboardMapping, getKeyboardLayoutId } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; -import { OS, OperatingSystem, isMacintosh, isWindows, isLinux } from 'vs/base/common/platform'; +import { OS, OperatingSystem, isMacintosh, isWindows } from 'vs/base/common/platform'; import { WindowsKeyboardMapper } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper'; import { MacLinuxFallbackKeyboardMapper } from 'vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper'; import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding'; @@ -41,6 +41,10 @@ export class BrowserKeyboardMapperFactory { private _mru: KeymapInfo[]; private _activeKeymapInfo: KeymapInfo | null; + get activeKeymap(): KeymapInfo | null { + return this._activeKeymapInfo; + } + get keymapInfos(): KeymapInfo[] { return this._keymapInfos; } @@ -233,21 +237,7 @@ export class BrowserKeyboardMapperFactory { } public setKeyboardLayout(layoutName: string) { - let allKeyboardLayouts = this.keymapInfos; - let matchedLayouts: KeymapInfo[] = []; - if (isWindows) { - matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).name === layoutName); - } - - if (isMacintosh) { - // todo, probably we should use layout.id? - matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).lang === layoutName); - } - - if (isLinux) { - // todo, probably we should use layout.id? - matchedLayouts = allKeyboardLayouts.filter(layout => (layout.layout).layout === layoutName); - } + let matchedLayouts: KeymapInfo[] = this.keymapInfos.filter(keymapInfo => getKeyboardLayoutId(keymapInfo.layout) === layoutName); if (matchedLayouts.length > 0) { this.setActiveKeymapInfo(matchedLayouts[0]); @@ -498,8 +488,8 @@ class BrowserKeymapService extends Disposable implements IKeymapService { constructor( @IEnvironmentService environmentService: IEnvironmentService, - @IConfigurationService configurationService: IConfigurationService, @IFileService fileService: IFileService, + @IConfigurationService private configurationService: IConfigurationService, ) { super(); const keyboardConfig = configurationService.getValue<{ layout: string }>('keyboard'); @@ -530,6 +520,8 @@ class BrowserKeymapService extends Disposable implements IKeymapService { this._userKeyboardLayout.initialize().then(() => { if (this._userKeyboardLayout.keyboardLayout) { BrowserKeyboardMapperFactory.INSTANCE.registerKeyboardLayout(this._userKeyboardLayout.keyboardLayout); + + this.setUserKeyboardLayoutIfMatched(); } }); @@ -548,10 +540,24 @@ class BrowserKeymapService extends Disposable implements IKeymapService { } } - // TODO: trigger keymap update + this.setUserKeyboardLayoutIfMatched(); })); } + setUserKeyboardLayoutIfMatched() { + const keyboardConfig = this.configurationService.getValue<{ layout: string }>('keyboard'); + const layout = keyboardConfig.layout; + + if (layout && this._userKeyboardLayout.keyboardLayout) { + if (getKeyboardLayoutId(this._userKeyboardLayout.keyboardLayout.layout) === layout && BrowserKeyboardMapperFactory.INSTANCE.activeKeymap) { + + if (!this._userKeyboardLayout.keyboardLayout.equal(BrowserKeyboardMapperFactory.INSTANCE.activeKeymap)) { + BrowserKeyboardMapperFactory.INSTANCE.setActiveKeymapInfo(this._userKeyboardLayout.keyboardLayout); + } + } + } + } + registerKeyboardListener() { this.layoutChangeListener.value = BrowserKeyboardMapperFactory.INSTANCE.onDidChangeKeyboardMapper(() => { this._onDidChangeKeyboardMapper.fire(); diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index 6edaa141dc095..c4159da4c6f8b 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -127,7 +127,7 @@ export function areKeyboardLayoutsEqual(a: IKeyboardLayoutInfo | null, b: IKeybo return false; } -export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { +export function parseKeyboardLayoutDescription(layout: IKeyboardLayoutInfo | null): { label: string, description: string } { if (!layout) { return { label: '', description: '' }; } @@ -177,6 +177,18 @@ export function parseKeyboardLayout(layout: IKeyboardLayoutInfo | null): { label }; } +export function getKeyboardLayoutId(layout: IKeyboardLayoutInfo): string { + if ((layout).name) { + return (layout).name; + } + + if ((layout).id) { + return (layout).id; + } + + return (layout).layout; +} + function deserializeMapping(serializedMapping: ISerializedMapping) { let mapping = serializedMapping; @@ -282,6 +294,18 @@ export class KeymapInfo { return score; } + equal(other: KeymapInfo): boolean { + if (this.isUserKeyboardLayout !== other.isUserKeyboardLayout) { + return false; + } + + if (getKeyboardLayoutId(this.layout) !== getKeyboardLayoutId(other.layout)) { + return false; + } + + return this.fuzzyEqual(other.mapping); + } + fuzzyEqual(other: IRawMixedKeyboardMapping): boolean { for (let key in other) { if (isWindows && (key === 'Backslash' || key === 'KeyQ')) { From 5ec5ca6f2cafd2175bd5e2af7cc8c4e16dfdc197 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 11:54:26 -0700 Subject: [PATCH 203/364] Have `.get` return promise directly --- .../webview/browser/pre/service-worker.js | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index d36d3cca24e6b..09157ea51214d 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -29,10 +29,11 @@ class RequestStore { /** * @param {string} webviewId * @param {string} path - * @return {RequestStoreEntry | undefined} + * @return {Promise | undefined} */ get(webviewId, path) { - return this.map.get(this._key(webviewId, path)); + const entry = this.map.get(this._key(webviewId, path)); + return entry && entry.promise; } /** @@ -43,18 +44,19 @@ class RequestStore { create(webviewId, path) { const existing = this.get(webviewId, path); if (existing) { - return existing.promise; + return existing; } let resolve; const promise = new Promise(r => resolve = r); const entry = { resolve, promise }; - this.map.set(this._key(webviewId, path), entry); + const key = this._key(webviewId, path); + this.map.set(key, entry); const dispose = () => { clearTimeout(timeout); - const existing = this.get(webviewId, path); - if (existing === entry) { - return this.map.delete(this._key(webviewId, path)); + const existingEntry = this.map.get(key); + if (existingEntry === entry) { + return this.map.delete(key); } }; const timeout = setTimeout(dispose, resolveTimeout); @@ -68,7 +70,7 @@ class RequestStore { * @return {boolean} */ resolve(webviewId, path, result) { - const entry = this.get(webviewId, path); + const entry = this.map.get(this._key(webviewId, path)); if (!entry) { return false; } @@ -185,7 +187,7 @@ async function processResourceRequest(event, requestUrl) { // Check if we've already resolved this request const existing = resourceRequestStore.get(webviewId, resourcePath); if (existing) { - return existing.promise.then(resolveResourceEntry); + return existing.then(resolveResourceEntry); } parentClient.postMessage({ @@ -233,7 +235,7 @@ async function processLocalhostRequest(event, requestUrl) { // Check if we've already resolved this request const existing = localhostRequestStore.get(webviewId, origin); if (existing) { - return existing.promise.then(resolveRedirect); + return existing.then(resolveRedirect); } parentClient.postMessage({ From 6d88e8b576ebc19cf707032c9c4b7b238e1cc564 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 12:00:26 -0700 Subject: [PATCH 204/364] Make sure we wait until service worker is ready before creating content --- .../contrib/webview/browser/pre/main.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index b46a63a7c8f5e..caef053b16f8f 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -119,8 +119,12 @@ // Service worker for resource loading const FAKE_LOAD = !!navigator.serviceWorker; - if (navigator.serviceWorker) { - navigator.serviceWorker.register('service-worker.js'); + + const workerReady = new Promise(resolve => { + if (!navigator.serviceWorker) { + resolve(); + } + navigator.serviceWorker.register('service-worker.js').finally(resolve); function forwardFromHostToWorker(channel) { host.onMessage(channel, event => { @@ -137,7 +141,7 @@ host.postMessage(event.data.channel, event.data); } }); - } + }); /** * @param {HTMLDocument?} document @@ -234,7 +238,6 @@ document.addEventListener('DOMContentLoaded', () => { const idMatch = document.location.search.match(/\bid=([\w-]+)/); const ID = idMatch ? idMatch[1] : undefined; - if (!document.body) { return; } @@ -261,8 +264,16 @@ } }); + // update iframe-contents - host.onMessage('content', (_event, data) => { + let updateId = 0; + host.onMessage('content', async (_event, data) => { + const currentUpdateId = ++updateId; + await workerReady; + if (currentUpdateId !== updateId) { + return; + } + const options = data.options; const text = data.contents; From 355b5692ff64a3604ddad9ea4a8076f6fb9545cd Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 14:36:48 -0700 Subject: [PATCH 205/364] Add version check to service worker Try to make sure our page is talking to the expected version of the service worker --- .../contrib/webview/browser/pre/index.html | 99 ++++++++++++++----- .../contrib/webview/browser/pre/main.js | 28 +----- .../webview/browser/pre/service-worker.js | 16 ++- 3 files changed, 94 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index 9727c148c3fc4..4128a65be4a87 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -16,38 +16,91 @@ - + + \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index caef053b16f8f..c30f0c79592bf 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -99,7 +99,8 @@ * postMessage: (channel: string, data?: any) => void, * onMessage: (channel: string, handler: any) => void, * injectHtml?: (document: HTMLDocument) => void, - * focusIframeOnCreate?: boolean + * focusIframeOnCreate?: boolean, + * ready?: Promise * }} HostCommunications */ @@ -120,29 +121,6 @@ // Service worker for resource loading const FAKE_LOAD = !!navigator.serviceWorker; - const workerReady = new Promise(resolve => { - if (!navigator.serviceWorker) { - resolve(); - } - navigator.serviceWorker.register('service-worker.js').finally(resolve); - - function forwardFromHostToWorker(channel) { - host.onMessage(channel, event => { - navigator.serviceWorker.ready.then(registration => { - registration.active.postMessage({ channel: channel, data: event.data.args }); - }); - }); - } - forwardFromHostToWorker('did-load-resource'); - forwardFromHostToWorker('did-load-localhost'); - - navigator.serviceWorker.addEventListener('message', event => { - if (['load-resource', 'load-localhost'].includes(event.data.channel)) { - host.postMessage(event.data.channel, event.data); - } - }); - }); - /** * @param {HTMLDocument?} document * @param {HTMLElement?} body @@ -269,7 +247,7 @@ let updateId = 0; host.onMessage('content', async (_event, data) => { const currentUpdateId = ++updateId; - await workerReady; + await host.ready; if (currentUpdateId !== updateId) { return; } diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index 09157ea51214d..7e200dc4e980b 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -2,6 +2,8 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +const VERSION = 1; + /** * Root path for resources */ @@ -106,8 +108,20 @@ const notFoundResponse = new Response('Not Found', { status: 404, }); -self.addEventListener('message', (event) => { +self.addEventListener('message', async (event) => { switch (event.data.channel) { + case 'version': + { + self.clients.get(event.source.id).then(client => { + if (client) { + client.postMessage({ + channel: 'version', + version: VERSION + }); + } + }); + return; + } case 'did-load-resource': { const webviewId = getWebviewIdForClient(event.source); From 02db6311403f8d9967b13d4a73e764d034aa3677 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 14:38:58 -0700 Subject: [PATCH 206/364] Don't use clone as much --- .../contrib/webview/browser/pre/service-worker.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index 7e200dc4e980b..23f08be028162 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -104,9 +104,8 @@ const resourceRequestStore = new RequestStore(); */ const localhostRequestStore = new RequestStore(); -const notFoundResponse = new Response('Not Found', { - status: 404, -}); +const notFound = () => + new Response('Not Found', { status: 404, }); self.addEventListener('message', async (event) => { switch (event.data.channel) { @@ -176,7 +175,7 @@ async function processResourceRequest(event, requestUrl) { const client = await self.clients.get(event.clientId); if (!client) { console.log('Could not find inner client for request'); - return notFoundResponse.clone(); + return notFound(); } const webviewId = getWebviewIdForClient(client); @@ -184,7 +183,7 @@ async function processResourceRequest(event, requestUrl) { function resolveResourceEntry(entry) { if (!entry) { - return notFoundResponse.clone(); + return notFound(); } return new Response(entry.body, { status: 200, @@ -195,7 +194,7 @@ async function processResourceRequest(event, requestUrl) { const parentClient = await getOuterIframeClient(webviewId); if (!parentClient) { console.log('Could not find parent client for request'); - return notFoundResponse.clone(); + return notFound(); } // Check if we've already resolved this request @@ -243,7 +242,7 @@ async function processLocalhostRequest(event, requestUrl) { const parentClient = await getOuterIframeClient(webviewId); if (!parentClient) { console.log('Could not find parent client for request'); - return notFoundResponse.clone(); + return notFound(); } // Check if we've already resolved this request From d0796114464da951e6447e80e85142404c814e13 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 15:35:19 -0700 Subject: [PATCH 207/364] Move host javascript to own file --- .../contrib/webview/browser/pre/host.js | 90 +++++++++++++++++++ .../contrib/webview/browser/pre/index.html | 89 +----------------- 2 files changed, 91 insertions(+), 88 deletions(-) create mode 100644 src/vs/workbench/contrib/webview/browser/pre/host.js diff --git a/src/vs/workbench/contrib/webview/browser/pre/host.js b/src/vs/workbench/contrib/webview/browser/pre/host.js new file mode 100644 index 0000000000000..71acbf4b8a311 --- /dev/null +++ b/src/vs/workbench/contrib/webview/browser/pre/host.js @@ -0,0 +1,90 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +// @ts-check +(function () { + const id = document.location.search.match(/\bid=([\w-]+)/)[1]; + + const hostMessaging = new class HostMessaging { + constructor() { + this.handlers = new Map(); + window.addEventListener('message', (e) => { + if (e.data && (e.data.command === 'onmessage' || e.data.command === 'do-update-state')) { + // Came from inner iframe + this.postMessage(e.data.command, e.data.data); + return; + } + + const channel = e.data.channel; + const handler = this.handlers.get(channel); + if (handler) { + handler(e, e.data.args); + } else { + console.log('no handler for ', e); + } + }); + } + + postMessage(channel, data) { + window.parent.postMessage({ target: id, channel, data }, '*'); + } + + onMessage(channel, handler) { + this.handlers.set(channel, handler); + } + }(); + + const workerReady = new Promise(async (resolveWorkerReady) => { + if (!navigator.serviceWorker) { + resolveWorkerReady(); + } + + const expectedWorkerVersion = 1; + + navigator.serviceWorker.register('service-worker.js').then(async registration => { + await navigator.serviceWorker.ready; + + const versionHandler = (event) => { + if (event.data.channel !== 'version') { + return; + } + + navigator.serviceWorker.removeEventListener('message', versionHandler); + if (event.data.version === expectedWorkerVersion) { + return resolveWorkerReady(); + } else { + // If we have the wrong version, try once to unregister and re-register + return registration.unregister() + .then(() => navigator.serviceWorker.register('service-worker.js')) + .then(navigator.serviceWorker.ready) + .finally(resolveWorkerReady); + } + }; + navigator.serviceWorker.addEventListener('message', versionHandler); + registration.active.postMessage({ channel: 'version' }); + }); + + const forwardFromHostToWorker = (channel) => { + hostMessaging.onMessage(channel, event => { + navigator.serviceWorker.ready.then(registration => { + registration.active.postMessage({ channel: channel, data: event.data.args }); + }); + }); + }; + forwardFromHostToWorker('did-load-resource'); + forwardFromHostToWorker('did-load-localhost'); + + navigator.serviceWorker.addEventListener('message', event => { + if (['load-resource', 'load-localhost'].includes(event.data.channel)) { + hostMessaging.postMessage(event.data.channel, event.data); + } + }); + }); + var createWebviewManager; + createWebviewManager({ + postMessage: hostMessaging.postMessage.bind(hostMessaging), + onMessage: hostMessaging.onMessage.bind(hostMessaging), + ready: workerReady, + }); +}()); \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index 4128a65be4a87..03337a5f6af1e 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -13,94 +13,7 @@ - + \ No newline at end of file From 6c22b0bf877efcf7aa84dc406d92ca6b2d614e90 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 15:37:38 -0700 Subject: [PATCH 208/364] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9fcfda77b221..8ea694500f24b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "cb72005ab15a4d369209542fbfa4e64c06db2111", + "distro": "8bfb613ef059967ffe5a69e3b151c29885c8c108", "author": { "name": "Microsoft Corporation" }, From d31a864e59f5d443f5ef7a779a0bfd86486a5af5 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Thu, 20 Jun 2019 15:55:23 -0700 Subject: [PATCH 209/364] Remove icon explorations before shipping stable --- src/vs/base/browser/ui/actionbar/actionbar.ts | 3 - src/vs/base/browser/ui/tree/media/tree.css | 10 - src/vs/workbench/browser/layout.ts | 30 +- src/vs/workbench/browser/media/icons.css | 1268 ----------------- .../media/images/activitybar/debug-alt1.svg | 18 - .../images/activitybar/extensions-alt1.svg | 6 - .../media/images/activitybar/files-alt1.svg | 3 - .../media/images/activitybar/git-alt1.svg | 13 - .../media/images/activitybar/more-alt1.svg | 5 - .../images/activitybar/references-alt1.svg | 4 - .../media/images/activitybar/search-alt1.svg | 11 - .../images/activitybar/settings-alt1.svg | 3 - .../browser/media/images/debug/add-alt1.svg | 3 - .../images/debug/breakpoint-activate-alt1.svg | 3 - .../media/images/debug/breakpoint-alt1.svg | 3 - .../debug/breakpoint-conditional-alt1.svg | 3 - .../images/debug/breakpoint-function-alt1.svg | 3 - .../breakpoint-function-disabled-alt1.svg | 3 - .../breakpoint-function-unverified-alt1.svg | 3 - .../images/debug/breakpoint-log-alt1.svg | 3 - .../debug/breakpoint-log-unverified-alt1.svg | 3 - .../debug/breakpoint-unverified-alt1.svg | 3 - .../browser/media/images/debug/close-alt1.svg | 5 - .../media/images/debug/continue-alt1.svg | 4 - .../debug/current-and-breakpoint-alt1.svg | 4 - .../media/images/debug/current-arrow-alt1.svg | 3 - .../media/images/debug/disconnect-alt1.svg | 3 - .../browser/media/images/debug/drag-alt1.svg | 8 - .../browser/media/images/debug/gear-alt1.svg | 4 - .../browser/media/images/debug/pause-alt1.svg | 3 - .../browser/media/images/debug/repl-alt1.svg | 5 - .../media/images/debug/restart-alt1.svg | 5 - .../debug/stackframe-and-breakpoint-alt1.svg | 4 - .../images/debug/stackframe-arrow-alt1.svg | 3 - .../browser/media/images/debug/start-alt1.svg | 3 - .../media/images/debug/step-into-alt1.svg | 11 - .../media/images/debug/step-out-alt1.svg | 11 - .../media/images/debug/step-over-alt1.svg | 9 - .../browser/media/images/debug/stop-alt1.svg | 3 - .../media/images/editor/open-change-alt1.svg | 8 - .../images/editor/split-horizontal-alt1.svg | 4 - .../images/editor/split-vertical-alt1.svg | 4 - .../media/images/explorer/add-file-alt1.svg | 5 - .../media/images/explorer/add-folder-alt1.svg | 5 - .../media/images/explorer/close-alt1.svg | 5 - .../media/images/explorer/collapse-alt1.svg | 4 - .../media/images/explorer/layout-alt1.svg | 3 - .../media/images/explorer/more-alt1.svg | 5 - .../media/images/explorer/refresh-alt1.svg | 3 - .../media/images/explorer/save-alt1.svg | 6 - .../media/images/extensions/clear-alt1.svg | 7 - .../media/images/extensions/download-alt1.svg | 4 - .../media/images/extensions/gear-alt1.svg | 4 - .../images/extensions/star-empty-alt1.svg | 4 - .../images/extensions/star-full-alt1.svg | 4 - .../images/extensions/star-half-alt1.svg | 3 - .../browser/media/images/find/close-alt1.svg | 4 - .../media/images/find/collapse-alt1.svg | 3 - .../browser/media/images/find/expand-alt1.svg | 3 - .../browser/media/images/find/next-alt1.svg | 3 - .../media/images/find/previous-alt1.svg | 3 - .../media/images/find/replace-all-alt1.svg | 9 - .../media/images/find/replace-alt1.svg | 6 - .../media/images/find/selection-alt1.svg | 3 - .../browser/media/images/git/check-alt1.svg | 3 - .../browser/media/images/git/clean-alt1.svg | 3 - .../browser/media/images/git/close-alt1.svg | 4 - .../media/images/git/gotofile-alt1.svg | 5 - .../browser/media/images/git/initialze.svg | 3 - .../browser/media/images/git/next-alt1.svg | 3 - .../media/images/git/previous-alt1.svg | 3 - .../browser/media/images/git/refresh-alt1.svg | 3 - .../browser/media/images/git/stage-alt1.svg | 3 - .../browser/media/images/git/unstage-alt1.svg | 4 - .../media/images/git/whitespace-alt1.svg | 3 - .../media/images/intellisense/array-alt1.svg | 4 - .../images/intellisense/boolean-alt1.svg | 5 - .../media/images/intellisense/class-alt1.svg | 3 - .../media/images/intellisense/close-alt1.svg | 4 - .../media/images/intellisense/color-alt1.svg | 3 - .../images/intellisense/constant-alt1.svg | 3 - .../images/intellisense/enum-member-alt1.svg | 4 - .../images/intellisense/enumerator-alt1.svg | 4 - .../media/images/intellisense/event-alt1.svg | 3 - .../media/images/intellisense/field-alt1.svg | 3 - .../media/images/intellisense/file-alt1.svg | 3 - .../media/images/intellisense/folder-alt1.svg | 3 - .../media/images/intellisense/info-alt1.svg | 3 - .../images/intellisense/interface-alt1.svg | 5 - .../media/images/intellisense/key-alt1.svg | 8 - .../images/intellisense/keyword-alt1.svg | 3 - .../images/intellisense/lightbulb-alt1.svg | 3 - .../intellisense/lightbulb-autofix-alt1.svg | 4 - .../media/images/intellisense/method-alt1.svg | 3 - .../images/intellisense/namespace-alt1.svg | 4 - .../images/intellisense/numeric-alt1.svg | 6 - .../images/intellisense/operator-alt1.svg | 8 - .../images/intellisense/parameter-alt1.svg | 5 - .../images/intellisense/property-alt1.svg | 3 - .../images/intellisense/reference-alt1.svg | 5 - .../media/images/intellisense/ruler-alt1.svg | 3 - .../images/intellisense/snippet-alt1.svg | 9 - .../media/images/intellisense/string-alt1.svg | 4 - .../images/intellisense/structure-alt1.svg | 3 - .../images/intellisense/variable-alt1.svg | 4 - .../browser/media/images/misc/clear-alt1.svg | 7 - .../browser/media/images/misc/fold-alt1.svg | 3 - .../media/images/misc/gotofile-alt1.svg | 5 - .../browser/media/images/misc/json-alt1.svg | 14 - .../media/images/misc/keyboard-alt1.svg | 15 - .../browser/media/images/misc/more-alt1.svg | 5 - .../media/images/misc/precedence-alt1.svg | 7 - .../media/images/misc/preview-alt1.svg | 4 - .../media/images/misc/preview-icon-alt1.svg | 7 - .../browser/media/images/misc/split-alt1.svg | 4 - .../browser/media/images/misc/unfold-alt1.svg | 3 - .../media/images/notifications/close-alt1.svg | 4 - .../images/notifications/closeall-alt1.svg | 5 - .../images/notifications/configure-alt1.svg | 4 - .../media/images/notifications/down-alt1.svg | 10 - .../media/images/notifications/error-alt1.svg | 3 - .../media/images/notifications/info-alt1.svg | 5 - .../media/images/notifications/up-alt1.svg | 10 - .../images/notifications/warning-alt1.svg | 5 - .../browser/media/images/panel/add-alt1.svg | 3 - .../browser/media/images/panel/clear-alt1.svg | 7 - .../media/images/panel/close-all-alt1.svg | 5 - .../browser/media/images/panel/close-alt1.svg | 4 - .../media/images/panel/collapse-all-alt1.svg | 4 - .../browser/media/images/panel/down-alt1.svg | 10 - .../browser/media/images/panel/gear-alt1.svg | 4 - .../media/images/panel/gotofile-alt1.svg | 5 - .../browser/media/images/panel/kill-alt1.svg | 8 - .../media/images/panel/output-lock-alt1.svg | 3 - .../media/images/panel/output-unlock-alt1.svg | 3 - .../images/panel/split-horizontal-alt1.svg | 4 - .../images/panel/split-vertical-alt1.svg | 4 - .../browser/media/images/panel/up-alt1.svg | 10 - .../images/search/case-sensitive-alt1.svg | 4 - .../media/images/search/clear-alt1.svg | 7 - .../media/images/search/collapse-all-alt1.svg | 4 - .../media/images/search/collapse-alt1.svg | 3 - .../media/images/search/exclude-alt1.svg | 5 - .../media/images/search/expand-alt1.svg | 3 - .../browser/media/images/search/more-alt1.svg | 5 - .../media/images/search/refresh-alt1.svg | 3 - .../media/images/search/regex-alt1.svg | 4 - .../media/images/search/remove-alt1.svg | 4 - .../media/images/search/replace-all-alt1.svg | 9 - .../media/images/search/replace-alt1.svg | 6 - .../browser/media/images/search/stop-alt1.svg | 3 - .../media/images/search/whole-word-alt1.svg | 7 - .../browser/media/images/tree/close-alt1.svg | 4 - .../media/images/tree/collapse-alt1.svg | 3 - .../browser/media/images/tree/dirty-alt1.svg | 3 - .../browser/media/images/tree/expand-alt1.svg | 3 - .../media/images/tree/expand-empty.svg | 2 - src/vs/workbench/browser/style.ts | 1 - .../browser/workbench.contribution.ts | 6 - 159 files changed, 1 insertion(+), 2048 deletions(-) delete mode 100644 src/vs/workbench/browser/media/icons.css delete mode 100644 src/vs/workbench/browser/media/images/activitybar/debug-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/extensions-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/files-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/git-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/more-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/references-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/search-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/activitybar/settings-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/add-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-activate-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-conditional-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-function-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-function-disabled-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-function-unverified-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-log-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-log-unverified-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/breakpoint-unverified-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/continue-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/current-and-breakpoint-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/current-arrow-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/disconnect-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/drag-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/gear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/pause-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/repl-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/restart-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/stackframe-and-breakpoint-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/stackframe-arrow-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/start-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/step-into-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/step-out-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/step-over-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/debug/stop-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/editor/open-change-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/editor/split-horizontal-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/editor/split-vertical-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/add-file-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/add-folder-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/collapse-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/layout-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/more-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/refresh-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/explorer/save-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/extensions/clear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/extensions/download-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/extensions/gear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/extensions/star-empty-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/extensions/star-full-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/extensions/star-half-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/collapse-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/expand-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/next-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/previous-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/replace-all-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/replace-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/find/selection-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/check-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/clean-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/gotofile-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/initialze.svg delete mode 100644 src/vs/workbench/browser/media/images/git/next-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/previous-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/refresh-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/stage-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/unstage-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/git/whitespace-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/array-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/boolean-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/class-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/color-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/constant-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/enum-member-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/enumerator-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/event-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/field-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/file-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/folder-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/info-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/interface-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/key-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/lightbulb-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/lightbulb-autofix-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/method-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/namespace-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/numeric-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/operator-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/parameter-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/property-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/reference-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/ruler-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/snippet-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/string-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/structure-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/intellisense/variable-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/clear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/fold-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/gotofile-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/json-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/keyboard-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/more-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/precedence-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/preview-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/preview-icon-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/split-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/misc/unfold-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/closeall-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/configure-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/down-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/error-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/info-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/up-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/notifications/warning-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/add-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/clear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/close-all-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/collapse-all-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/down-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/gear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/gotofile-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/kill-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/output-lock-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/output-unlock-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/split-horizontal-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/split-vertical-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/panel/up-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/case-sensitive-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/clear-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/collapse-all-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/collapse-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/exclude-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/expand-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/more-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/refresh-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/regex-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/remove-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/replace-all-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/replace-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/stop-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/search/whole-word-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/tree/close-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/tree/collapse-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/tree/dirty-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/tree/expand-alt1.svg delete mode 100644 src/vs/workbench/browser/media/images/tree/expand-empty.svg diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index e76fd3a6bbcca..ffef9180cc64a 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -259,9 +259,6 @@ export class ActionViewItem extends BaseActionViewItem { this.label.setAttribute('role', 'menuitem'); } else { this.label.setAttribute('role', 'button'); - - // TODO @misolori remove before shipping stable - this.label.setAttribute('data-title', this._action.id); } } diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 85dcafe22b1bd..262b33ded2248 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -22,16 +22,6 @@ left: 10px; } -/* TODO @misolori remove before shipping stable */ -body:not([data-exploration="icon-exploration"]) .monaco-tl-indent { - left: 16px; -} - -/* TODO @misolori remove before shipping stable */ -body:not([data-exploration="icon-exploration"]) .hide-arrows .monaco-tl-indent { - left: 10px; -} - .monaco-tl-indent > svg { overflow: visible; } diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index e06870b2bb791..87171e900c61c 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -45,8 +45,6 @@ enum Settings { ZEN_MODE_RESTORE = 'zenMode.restore', - // TODO @misolori remove before shipping stable - ICON_EXPLORATION_ENABLED = 'workbench.iconExploration.enabled' } enum Storage { @@ -160,12 +158,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi wasSideBarVisible: false, wasPanelVisible: false, transitionDisposeables: new DisposableStore() - }, - - // TODO @misolori remove before shipping stable - iconExploration: { - enabled: false } + }; constructor( @@ -299,11 +293,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi const newMenubarVisibility = this.configurationService.getValue(Settings.MENUBAR_VISIBLE); this.setMenubarVisibility(newMenubarVisibility, !!skipLayout); - // TODO @misolori remove before shipping stable - // Icon exploration on setting change - const newIconExplorationEnabled = this.configurationService.getValue(Settings.ICON_EXPLORATION_ENABLED); - this.setIconExploration(newIconExplorationEnabled); - } private setSideBarPosition(position: Position): void { @@ -417,10 +406,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Zen mode enablement this.state.zenMode.restore = this.storageService.getBoolean(Storage.ZEN_MODE_ENABLED, StorageScope.WORKSPACE, false) && this.configurationService.getValue(Settings.ZEN_MODE_RESTORE); - // TODO @misolori remove before shipping stable - // Icon exploration - this.state.iconExploration.enabled = this.configurationService.getValue(Settings.ICON_EXPLORATION_ENABLED); - this.setIconExploration(this.state.iconExploration.enabled); } private resolveEditorsToOpen(fileService: IFileService): Promise | IResourceEditor[] { @@ -689,19 +674,6 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } } - // TODO @misolori remove before shipping stable - private setIconExploration(enabled: boolean): void { - this.state.iconExploration.enabled = enabled; - - // Update DOM - if (enabled) { - document.body.dataset.exploration = 'icon-exploration'; - } else { - document.body.dataset.exploration = ''; - } - - } - protected createWorkbenchLayout(instantiationService: IInstantiationService): void { const titleBar = this.getPart(Parts.TITLEBAR_PART); const editorPart = this.getPart(Parts.EDITOR_PART); diff --git a/src/vs/workbench/browser/media/icons.css b/src/vs/workbench/browser/media/icons.css deleted file mode 100644 index a730544fcb7d9..0000000000000 --- a/src/vs/workbench/browser/media/icons.css +++ /dev/null @@ -1,1268 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/**************** - Colors -****************/ -:root { - --blue: #00539c; - --gray: #424242; - --grayLight: #848484; - --green: #388a34; - --greenLight: #9cce9c; - --orange: #c27d1a; - --orangeLight: #ff8e00; - --purple: #652d90; - --red: #a31515; - --redLight: #e51400; - --yellow: #fc0; -} - -:root .vs-dark { - --blue: #75beff; - --gray: #c5c5c5; - --grayLight: #848484; - --green: #89d185; - --greenLight: #9cce9c; - --orange: #e8ab53; - --orangeLight: #ff8e00; - --purple: #b180d7; - --red: #f48771; - --redLight: #e51400; - --yellow: #fc0; -} - -:root .hc-black { - --blue: #75beff; - --gray: #FFF; - --grayLight: #FFF; - --green: #89d185; - --greenLight: #9cce9c; - --orange: #e8ab53; - --orangeLight: #ff8e00; - --purple: #b180d7; - --red: #f48771; - --redLight: #e51400; - --yellow: #fc0; -} - - -/**************** - Base -****************/ -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header[aria-label="Open Editors Section"] > .actions .action-label.icon, -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header > .actions .action-label.explorer-action.icon, -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header > .actions .action-label.toolbar-toggle-more.icon, -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label^="Explorer"] .icon, -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Search actions"] .icon, -body[data-exploration^="icon-exploration"] .monaco-findInput > .controls .monaco-custom-checkbox::before, -body[data-exploration^="icon-exploration"] .monaco-workbench .search-view .query-details .file-types .controls > .monaco-custom-checkbox.useExcludesAndIgnoreFiles::before, -body[data-exploration^="icon-exploration"] .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude::before, -body[data-exploration^="icon-exploration"] .search-view .search-widget .replace-container .monaco-action-bar .action-item .icon, -body[data-exploration^="icon-exploration"] .search-view a[class^="action-"], -body[data-exploration^="icon-exploration"] .monaco-workbench .search-view .query-details .more, -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Source Control: Git actions"] .icon[data-title="git.commit"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Source Control: Git actions"] .icon[data-title="git.refresh"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label="Debug actions"] .icon, -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .actions-container[aria-label^="Extensions"] .icon, -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.openFile2"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.unstage"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.stage"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.openChange"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title^="git.clean"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.cleanAll"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.stageAll"], -body[data-exploration^="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.unstageAll"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .content > .debug-viewlet .actions .action-label.icon, -body[data-exploration^="icon-exploration"] .monaco-workbench .debug-toolbar .drag-area, -body[data-exploration^="icon-exploration"] .monaco-workbench .debug-toolbar .action-label, -body[data-exploration^="icon-exploration"] .debug-breakpoint, -body[data-exploration^="icon-exploration"] .debug-viewlet .debug-breakpoints .breakpoint > .icon, -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage, -body[data-exploration^="icon-exploration"] .extension-ratings > .star, -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count > .octicon, -body[data-exploration^="icon-exploration"] .extension-editor > .header > .details > .subtitle .octicon, -body[data-exploration^="icon-exploration"] .monaco-toolbar .action-label.toolbar-toggle-more, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.panel > .title > .title-actions .monaco-action-bar .action-item .action-label, -body[data-exploration^="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon::before, -body[data-exploration^="icon-exploration"] .monaco-workbench .symbol-icon::before, -body[data-exploration^="icon-exploration"] .monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .close, -body[data-exploration^="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .readMore, -body[data-exploration^="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-title .icon.error, -body[data-exploration^="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-title .icon.warning, -body[data-exploration^="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item-icon, -body[data-exploration^="icon-exploration"] .monaco-workbench > .notifications-center > .notifications-center-header .clear-all-notifications-action, -body[data-exploration^="icon-exploration"] .monaco-workbench > .notifications-center > .notifications-center-header .hide-all-notifications-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .clear-notification-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .action-label, -body[data-exploration^="icon-exploration"] .monaco-workbench .activitybar > .content .monaco-action-bar .action-label[title="References"], -body[data-exploration^="icon-exploration"] .markers-panel .marker-icon, -body[data-exploration^="icon-exploration"] .markers-panel .monaco-tl-contents .actions .action-label.icon.markers-panel-action-quickfix, -body[data-exploration^="icon-exploration"] .monaco-tl-twistie.collapsible:not(.loading), -body[data-exploration^="icon-exploration"] .file-icon-themable-tree .monaco-tree-row.has-children .content::before, -body[data-exploration^="icon-exploration"] .file-icon-themable-tree .monaco-tree-row.has-children.expanded .content::before, -body[data-exploration^="icon-exploration"] .monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before, -body[data-exploration^="icon-exploration"] .monaco-tl-twistie.collapsible.collapsed:not(.loading), -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .close-editor-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.closeActiveEditor"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.splitEditor"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="git.openChange"], -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .replace-all::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .replace::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .previous::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .next::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .close-fw::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .expand::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .collapse::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .monaco-checkbox .label::before, -body[data-exploration^="icon-exploration"] .monaco-workbench .quick-open-sidebyside-vertical, -body[data-exploration^="icon-exploration"] .monaco-tree-action.collapse-all, -body[data-exploration^="icon-exploration"] .monaco-editor .debug-breakpoint, -body[data-exploration^="icon-exploration"] .monaco-editor .debug-focused-stack-frame, -body[data-exploration^="icon-exploration"] .monaco-editor .debug-top-stack-frame, -body[data-exploration^="icon-exploration"] .monaco-editor .debug-breakpoint-hint, -body[data-exploration^="icon-exploration"] .monaco-editor .debug-breakpoint-conditional, -body[data-exploration^="icon-exploration"] .monaco-editor .debug-breakpoint-log, -body[data-exploration^="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-title .severity-icon, -body[data-exploration^="icon-exploration"] .monaco-editor .margin-view-overlays .folding, -body[data-exploration^="icon-exploration"] .monaco-workbench .explorer-action.save-all, -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="git.init"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="_workbench.openUserSettingsEditor"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.compareEditor.previousChange"], -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header > .actions .action-label.icon[data-title="git.commit"], -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header > .actions .action-label.icon[data-title="git.refresh"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="references-view.refresh"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="references-view.clear"], -body[data-exploration^="icon-exploration"] .customview-tree .monaco-tree .custom-view-tree-node-item > .custom-view-tree-node-item-resourceLabel > .actions .action-label[data-title="references-view.remove"], -body[data-exploration^="icon-exploration"] .markers-panel .monaco-tl-contents .multiline-actions .action-label.octicon-chevron-up, -body[data-exploration^="icon-exploration"] .markers-panel .monaco-tl-contents .multiline-actions .action-label.octicon-chevron-down, -body[data-exploration^="icon-exploration"] .monaco-workbench .explorer-viewlet .action-close-all-files, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more, -body[data-exploration^="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .clear-input, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.openGlobalKeybindingsFile"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="settings.switchToJSON"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="markdown.showSource"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label.file-icon[title^="Preview"]::before, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="markdown.showPreviewToSide"], -body[data-exploration^="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label, -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.compareEditor.nextChange"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.compareEditor.previousChange"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.compareEditor.nextChange"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="git.openFile"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="git.openFile"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.openGlobalKeybindings"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="toggle.diff.ignoreTrimWhitespace"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="toggle.diff.ignoreTrimWhitespace"], -body[data-exploration^="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions .action-label.icon[data-title="peekview.close"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.splitEditor"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="git.openChange"], -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover, -body[data-exploration^="icon-exploration"] .monaco-workbench .explorer-viewlet .explorer-open-editors .monaco-list .monaco-list-row.dirty:not(:hover) > .monaco-action-bar .close-editor-action, -body[data-exploration^="icon-exploration"] .monaco-workbench .explorer-viewlet .explorer-open-editors .close-editor-action { - background-image: none !important; - background: var(--gray); - -webkit-mask-repeat: no-repeat; - -webkit-mask-position: center; - -webkit-mask-size: 16px; -} - -/* Center via Flexbox + Search expand */ -body[data-exploration^="icon-exploration"] .search-view .search-widget .toggle-replace-button.collapse, -body[data-exploration^="icon-exploration"] .search-view .search-widget .toggle-replace-button.expand, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .replace-all, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .replace, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .previous, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .next, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .close-fw, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .expand, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .collapse, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .monaco-checkbox .label { - display: flex; - align-items: center; - justify-content: center; - background-image: none !important; -} - -/* Before elements */ -body[data-exploration="icon-exploration"] .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked::before, -body[data-exploration^="icon-exploration"] .search-view .search-widget .toggle-replace-button.collapse::before, -body[data-exploration^="icon-exploration"] .search-view .search-widget .toggle-replace-button.expand::before, -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .replace-all::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .replace::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .previous::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .next::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .close-fw::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .expand::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .collapse::before, -body[data-exploration^="icon-exploration"] .monaco-editor .find-widget .monaco-checkbox .label::before, -body[data-exploration^="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .monaco-custom-checkbox::before { - content: ""; - width: 16px; - height: 16px; - background-color: var(--gray); - -webkit-mask-repeat: no-repeat; - -webkit-mask-position: center; - -webkit-mask-size: 16px; -} - -/* For icons that are a custom checkbox and use focus */ -body[data-exploration="icon-exploration"] .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked, -body[data-exploration^="icon-exploration"] .monaco-findInput > .controls .monaco-custom-checkbox, -body[data-exploration^="icon-exploration"] .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude, -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header, -body[data-exploration^="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .monaco-custom-checkbox { - background-image: none !important; -} - -body[data-exploration="icon-exploration"] .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked::before, -body[data-exploration^="icon-exploration"] .monaco-findInput > .controls .monaco-custom-checkbox::before, -body[data-exploration^="icon-exploration"] .markers-panel .monaco-tl-contents .multiline-actions .action-label.octicon-chevron-up::before, -body[data-exploration^="icon-exploration"] .markers-panel .monaco-tl-contents .multiline-actions .action-label.octicon-chevron-down::before, -body[data-exploration^="icon-exploration"] .monaco-workbench .search-view .query-details .file-types .controls > .monaco-custom-checkbox.useExcludesAndIgnoreFiles::before, -body[data-exploration^="icon-exploration"] .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude::before { - content: ""; - width: 16px; - height: 16px; - display: block; -} - -/******************** - ACTIVITY BAR -********************/ - -body[data-exploration^="icon-exploration"] .monaco-workbench .activitybar > .content .monaco-action-bar .badge .badge-content { - font-size: 9px; - font-weight: 600; - height: 16px; - line-height: 16px; - padding: 0 4px; -} - -body[data-exploration^="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label { - -webkit-mask-size: 24px !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label.explore { - -webkit-mask-image: url("images/activitybar/files-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label.search { - -webkit-mask-image: url("images/activitybar/search-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label.scm { - -webkit-mask-image: url("images/activitybar/git-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label.debug { - -webkit-mask-image: url("images/activitybar/debug-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label.extensions { - -webkit-mask-image: url("images/activitybar/extensions-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar .monaco-action-bar .action-label.update-activity { - -webkit-mask-image: url("images/activitybar/settings-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar > .content > .composite-bar > .monaco-action-bar .action-label.toggle-more { - -webkit-mask-image: url("images/activitybar/more-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .activitybar > .content .monaco-action-bar .action-label[title="References"] { - -webkit-mask-image: url("images/activitybar/references-alt1.svg"); -} - - -/**************** - Explorer -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .flip-editor-layout { - -webkit-mask-image: url("images/explorer/layout-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-action.save-all, -body[data-exploration="icon-exploration"] .monaco-workbench .save-all { - -webkit-mask-image: url("images/explorer/save-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-viewlet .action-close-all-files { - -webkit-mask-image: url("images/explorer/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-action.new-file { - -webkit-mask-image: url("images/explorer/add-file-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-action.new-folder { - -webkit-mask-image: url("images/explorer/add-folder-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-action.refresh-explorer, -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="references-view.refresh"] { - -webkit-mask-image: url("images/explorer/refresh-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-action.collapse-explorer { - -webkit-mask-image: url("images/explorer/collapse-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-toolbar .action-label.toolbar-toggle-more { - -webkit-mask-image: url("images/explorer/more-alt1.svg"); -} - - -/**************** - Search -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .search-action.refresh { - -webkit-mask-image: url("images/search/refresh-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .search-action.clear-search-results, -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="references-view.clear"] { - -webkit-mask-image: url("images/search/clear-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .search-action.collapse { - -webkit-mask-image: url("images/search/collapse-all-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .search-action.cancel-search { - -webkit-mask-image: url("images/search/stop-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .search-view .search-widget .replace-container .monaco-action-bar .action-item .icon { - -webkit-mask-image: url("images/search/replace-all-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .search-view .query-details .file-types .controls > .monaco-custom-checkbox.useExcludesAndIgnoreFiles::before, -body[data-exploration="icon-exploration"] .markers-panel-action-filter > .markers-panel-filter-controls > .markers-panel-filter-filesExclude::before { - -webkit-mask-image: url("images/search/exclude-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-custom-checkbox.monaco-case-sensitive::before { - -webkit-mask-image: url("images/search/case-sensitive-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-custom-checkbox.monaco-whole-word::before { - -webkit-mask-image: url("images/search/whole-word-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-custom-checkbox.monaco-regex::before { - -webkit-mask-image: url("images/search/regex-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .search-view .action-replace { - -webkit-mask-image: url("images/search/replace-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .search-view .action-replace-all { - -webkit-mask-image: url("images/search/replace-all-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .search-view .action-remove { - -webkit-mask-image: url("images/search/remove-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .search-view .query-details .more { - -webkit-mask-image: url("images/search/more-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .search-view .search-widget .toggle-replace-button.collapse::before { - -webkit-mask-image: url("images/search/collapse-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .search-view .search-widget .toggle-replace-button.expand::before { - -webkit-mask-image: url("images/search/expand-alt1.svg"); -} - - -/**************** - Git -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="git.init"] { - -webkit-mask-image: url("images/git/initialze.svg"); -} - -body[data-exploration="icon-exploration"] .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked::before, -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="git.commit"], -body[data-exploration="icon-exploration"] .monaco-panel-view .panel > .panel-header > .actions .action-label.icon[data-title="git.commit"] { - -webkit-mask-image: url("images/git/check-alt1.svg"); -} -/* Refresh */ -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="git.refresh"], -body[data-exploration="icon-exploration"] .monaco-panel-view .panel > .panel-header > .actions .action-label.icon[data-title="git.refresh"] { - -webkit-mask-image: url("images/git/refresh-alt1.svg"); -} -/* Stage */ -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label[data-title="git.stageChange"], -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.stageAll"], -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title="git.stage"] { - -webkit-mask-image: url("images/git/stage-alt1.svg"); -} -/* Unstage */ -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.unstageAll"], -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title="git.unstage"] { - -webkit-mask-image: url("images/git/unstage-alt1.svg"); -} -/* Discard */ -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label[data-title="git.revertChange"], -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource-group > .actions .action-label[data-title="git.cleanAll"], -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title="git.clean"] { - -webkit-mask-image: url("images/git/clean-alt1.svg"); -} -/* Open File */ -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="_workbench.openUserSettingsEditor"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="git.openFile"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="git.openFile"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.openGlobalKeybindings"], -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title="git.openFile2"] { - -webkit-mask-image: url("images/git/gotofile-alt1.svg"); -} -/* Chevrons */ -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.compareEditor.nextChange"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.compareEditor.nextChange"], -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label[data-title="editor.action.marker.next"], -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label[data-title="editor.action.dirtydiff.next"] { - -webkit-mask-image: url("images/git/next-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.compareEditor.previousChange"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.compareEditor.previousChange"], -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label[data-title="editor.action.marker.prev"], -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions > .monaco-action-bar .action-label[data-title="editor.action.dirtydiff.previous"] { - -webkit-mask-image: url("images/git/previous-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="toggle.diff.ignoreTrimWhitespace"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="toggle.diff.ignoreTrimWhitespace"]{ - -webkit-mask-image: url("images/git/whitespace-alt1.svg"); -} - - -/**************** - Debug -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-action.start, -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.continue"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .start-debug-action-item .icon { - -webkit-mask-image: url("images/debug/start-alt1.svg"); - background: var(--green) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-action.configure { - -webkit-mask-image: url("images/debug/gear-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-action.toggle-repl { - -webkit-mask-image: url("images/debug/repl-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-viewlet .debug-action.add-watch-expression, -body[data-exploration="icon-exploration"] .debug-viewlet .debug-action.add-function-breakpoint { - -webkit-mask-image: url("images/debug/add-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-viewlet .debug-action.remove-all { - -webkit-mask-image: url("images/debug/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-viewlet .debug-action.breakpoints-activate { - -webkit-mask-image: url("images/debug/breakpoint-activate-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .drag-area { - -webkit-mask-image: url("images/debug/drag-alt1.svg"); - background: var(--grayLight); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.stepOver"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.stepOver"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.stepBack"], -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.stepBack"] { - -webkit-mask-image: url("images/debug/step-over-alt1.svg"); - background: var(--blue) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.stepInto"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.stepInto"] { - -webkit-mask-image: url("images/debug/step-into-alt1.svg"); - background: var(--blue) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.stepOut"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.stepOut"] { - -webkit-mask-image: url("images/debug/step-out-alt1.svg"); - background: var(--blue) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.continue"], -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.rever"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.continue"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.rever"] { - -webkit-mask-image: url("images/debug/continue-alt1.svg"); - background: var(--blue) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.restart"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.restart"] { - -webkit-mask-image: url("images/debug/restart-alt1.svg"); - background: var(--green) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.pause"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.pause"] { - -webkit-mask-image: url("images/debug/pause-alt1.svg"); - background: var(--green) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.stop"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.stop"] { - -webkit-mask-image: url("images/debug/stop-alt1.svg"); - background: var(--red) !important; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .debug-toolbar .action-label[data-title="workbench.action.debug.disconnect"], -body[data-exploration="icon-exploration"] .monaco-workbench .part > .title > .title-actions .action-label[data-title="workbench.action.debug.disconnect"] { - -webkit-mask-image: url("images/debug/disconnect-alt1.svg"); - background: var(--red) !important; -} - -body[data-exploration="icon-exploration"] .debug-breakpoint, -body[data-exploration="icon-exploration"] .debug-breakpoint-hint, -body[data-exploration="icon-exploration"] .debug-breakpoint.icon, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-column::before { - -webkit-mask-image: url("images/debug/breakpoint-alt1.svg"); - background: var(--redLight) !important; -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-hint:not(.debug-breakpoint):not(.debug-breakpoint-conditional):not(.debug-top-stack-frame):not(.debug-focused-stack-frame):not(.debug-breakpoint-log) { - opacity: .5 !important; -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-disabled.icon { - -webkit-mask-image: url("images/debug/breakpoint-unverified-alt1.svg"); - background: var(--grayLight); -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-unverified, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-column.debug-breakpoint-disabled-column::before { - -webkit-mask-image: url("images/debug/breakpoint-alt1.svg"); - background: var(--grayLight); -} - -body[data-exploration="icon-exploration"] .monaco-editor .debug-top-stack-frame-column::before, -body[data-exploration="icon-exploration"] .monaco-editor .debug-top-stack-frame { - -webkit-mask-image: url("images/debug/current-arrow-alt1.svg"); - background: var(--yellow) !important; -} - -body[data-exploration="icon-exploration"] .monaco-editor .debug-top-stack-frame.debug-breakpoint, -body[data-exploration="icon-exploration"] .monaco-editor .debug-top-stack-frame.debug-breakpoint-conditional, -body[data-exploration="icon-exploration"] .monaco-editor .debug-top-stack-frame.debug-breakpoint-log, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-column.debug-breakpoint-column.debug-top-stack-frame-column::before { - -webkit-mask-image: url("images/debug/current-and-breakpoint-alt1.svg"); - background: var(--yellow) !important; -} - -body[data-exploration="icon-exploration"] .monaco-editor .debug-focused-stack-frame.debug-breakpoint, -body[data-exploration="icon-exploration"] .monaco-editor .debug-focused-stack-frame.debug-breakpoint-conditional, -body[data-exploration="icon-exploration"] .monaco-editor .debug-focused-stack-frame.debug-breakpoint-log { - -webkit-mask-image: url("images/debug/stackframe-and-breakpoint-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-log, -body[data-exploration="icon-exploration"] .debug-breakpoint-log.icon, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-column.debug-breakpoint-log-column::before { - -webkit-mask-image: url("images/debug/breakpoint-log-alt1.svg"); - background: var(--redLight) !important; -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-log-disabled, -body[data-exploration="icon-exploration"] .debug-breakpoint-log-disabled.icon, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-log-disabled-column::before { - -webkit-mask-image: url("images/debug/breakpoint-log-alt1.svg"); - background: var(--grayLight); -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-log-unverified, -body[data-exploration="icon-exploration"] .debug-breakpoint-log-unverified.icon, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-log-unverified-column::before { - -webkit-mask-image: url("images/debug/breakpoint-log-unverified-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-breakpoint-conditional, -body[data-exploration="icon-exploration"] .debug-breakpoint-conditional.icon, -body[data-exploration="icon-exploration"] .monaco-editor .debug-breakpoint-column.debug-breakpoint-conditional-column::before { - -webkit-mask-image: url("images/debug/breakpoint-conditional-alt1.svg"); - background: var(--redLight) !important; -} - -body[data-exploration="icon-exploration"] .monaco-editor .debug-focused-stack-frame { - -webkit-mask-image: url("images/debug/stackframe-arrow-alt1.svg"); - background: var(--green) !important; -} - -body[data-exploration="icon-exploration"] .debug-function-breakpoint, -body[data-exploration="icon-exploration"] .debug-function-breakpoint.icon { - -webkit-mask-image: url("images/debug/breakpoint-function-alt1.svg"); - background: var(--redLight) !important; -} - -body[data-exploration="icon-exploration"] .debug-function-breakpoint-unverified { - -webkit-mask-image: url("images/debug/breakpoint-function-unverified-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-function-breakpoint-disabled { - -webkit-mask-image: url("images/debug/breakpoint-function-disabled-alt1.svg"); -} - -/**************** - Extensions -****************/ - -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header { - align-items: center; -} - -body[data-exploration="icon-exploration"] .monaco-action-bar .action-item .action-label.clear-extensions { - -webkit-mask-image: url("images/extensions/clear-alt1.svg"); -} - -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count:not(:empty), -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header > .ratings { - display: flex; - align-items: center; - justify-content: center; -} - -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count > .octicon::before, -body[data-exploration^="icon-exploration"] .extension-editor > .header > .details > .subtitle .octicon::before { - content: "" !important; -} - -body[data-exploration^="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count > .octicon, -body[data-exploration^="icon-exploration"] .extension-ratings.small > .full { - width: 12px; - height: 12px; - -webkit-mask-size: 12px; -} - -body[data-exploration^="icon-exploration"] .extension-editor > .header > .details > .subtitle .octicon { - width: 16px; - height: 16px; - -webkit-mask-size: 16px; -} - -body[data-exploration^="icon-exploration"] .extension-editor > .header > .details > .subtitle > span:not(:first-child):not(:empty) { - position: relative; -} - -body[data-exploration^="icon-exploration"] .extension-editor > .header > .details > .subtitle > .install > .count { - margin-left: 22px; -} - -body[data-exploration^="icon-exploration"] .extension-editor > .header > .details > .subtitle .octicon { - position: absolute; - left: 14px; - top: 0; -} - -body[data-exploration="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .header-container > .header > .install-count > .octicon, -body[data-exploration="icon-exploration"] .extension-editor > .header > .details > .subtitle .octicon { - -webkit-mask-image: url("images/extensions/download-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .extension-ratings > .full { - -webkit-mask-image: url("images/extensions/star-full-alt1.svg"); - background: var(--orangeLight); -} - -body[data-exploration="icon-exploration"] .extension-ratings > .half { - -webkit-mask-image: url("images/extensions/star-half-alt1.svg"); - background: var(--orangeLight); -} - -body[data-exploration="icon-exploration"] .extension-ratings > .empty { - -webkit-mask-image: url("images/extensions/star-empty-alt1.svg"); - background: var(--gray); -} - -body[data-exploration="icon-exploration"] .extensions-viewlet > .extensions .extension > .details > .footer > .monaco-action-bar .action-item .action-label.extension-action.manage { - -webkit-mask-image: url("images/extensions/gear-alt1.svg"); -} - - -/**************** - Panels -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .hide-panel-action { - -webkit-mask-image: url("images/panel/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .maximize-panel-action { - -webkit-mask-image: url("images/panel/up-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .minimize-panel-action { - -webkit-mask-image: url("images/panel/down-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-tree-action.collapse-all { - -webkit-mask-image: url("images/panel/collapse-all-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .output-action.open-log-file { - -webkit-mask-image: url("images/panel/gotofile-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .output-action.open-log-file { - -webkit-mask-image: url("images/panel/gotofile-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .output-action.output-scroll-unlock { - -webkit-mask-image: url("images/panel/output-unlock-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .output-action.output-scroll-lock { - -webkit-mask-image: url("images/panel/output-lock-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .output-action.clear-output { - -webkit-mask-image: url("images/panel/clear-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .debug-action.clear-repl { - -webkit-mask-image: url("images/panel/clear-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .terminal-action.kill { - -webkit-mask-image: url("images/panel/kill-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .terminal-action.split, -body[data-exploration="icon-exploration"] .monaco-workbench .quick-open-sidebyside-vertical { - -webkit-mask-image: url("images/panel/split-horizontal-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .panel.right .terminal-action.split { - -webkit-mask-image: url("images/panel/split-vertical-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .terminal-action.new { - -webkit-mask-image: url("images/panel/add-alt1.svg"); -} - - -/**************** - IntelliSense -****************/ - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .details > .monaco-scrollable-element > .body > .header > .close { - -webkit-mask-image: url("images/intellisense/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .readMore { - -webkit-mask-image: url("images/intellisense/info-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon::before { - background-image: none !important; -} -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.method::before, -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.function::before, -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constructor::before { - -webkit-mask-image: url("images/intellisense/method-alt1.svg"); - background-color: var(--purple); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.field::before { - -webkit-mask-image: url("images/intellisense/field-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.event::before { - -webkit-mask-image: url("images/intellisense/event-alt1.svg"); - background-color: var(--orange); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.operator::before { - -webkit-mask-image: url("images/intellisense/operator-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.variable::before { - -webkit-mask-image: url("images/intellisense/variable-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.class::before { - -webkit-mask-image: url("images/intellisense/class-alt1.svg"); - background-color: var(--orange); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.interface::before { - -webkit-mask-image: url("images/intellisense/interface-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.struct::before { - -webkit-mask-image: url("images/intellisense/structure-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.type-parameter::before { - -webkit-mask-image: url("images/intellisense/parameter-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.module::before { - -webkit-mask-image: url("images/intellisense/namespace-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.property::before { - -webkit-mask-image: url("images/intellisense/property-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.unit::before { - -webkit-mask-image: url("images/intellisense/ruler-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.constant::before { - -webkit-mask-image: url("images/intellisense/constant-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.value::before, -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum::before { - -webkit-mask-image: url("images/intellisense/enumerator-alt1.svg"); - background-color: var(--orange); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.enum-member::before { - -webkit-mask-image: url("images/intellisense/enum-member-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.keyword::before { - -webkit-mask-image: url("images/intellisense/keyword-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.text::before { - -webkit-mask-image: url("images/intellisense/string-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.color::before { - -webkit-mask-image: url("images/intellisense/color-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.file::before { - -webkit-mask-image: url("images/intellisense/file-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.reference::before { - -webkit-mask-image: url("images/intellisense/reference-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.snippet::before { - -webkit-mask-image: url("images/intellisense/snippet-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .suggest-widget .monaco-list .monaco-list-row .suggest-icon.folder::before { - -webkit-mask-image: url("images/intellisense/folder-alt1.svg"); -} - -/**************** - Breadcrumbs -****************/ - -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item::before { - -webkit-mask-image: none; - background: transparent; -} - -body[data-exploration^="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title.breadcrumbs .breadcrumbs-control .monaco-breadcrumb-item .symbol-icon { - margin-left: 4px; -} - -body[data-exploration^="icon-exploration"] .monaco-quick-open-widget .quick-open-tree .quick-open-entry .quick-open-entry-icon::before { - left: 0; - top: -3px; -} - -body[data-exploration^="icon-exploration"] .monaco-workbench .breadcrumbs-control .symbol-icon::before, -body[data-exploration^="icon-exploration"] .monaco-workbench .monaco-breadcrumb-item .symbol-icon { - top: -2px; -} - -body[data-exploration^="icon-exploration"] .monaco-workbench .symbol-icon { - position: relative; - background-image: none !important; - -webkit-mask-position: left center; -} - -body[data-exploration^="icon-exploration"] .monaco-workbench .symbol-icon::before { - content: ""; - position: absolute; - left: -3px; - width: 16px; - height: 22px; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon::before { - -webkit-mask-image: url("images/intellisense/field-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.constant::before { - -webkit-mask-image: url("images/intellisense/constant-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.enum::before { - -webkit-mask-image: url("images/intellisense/enumerator-alt1.svg"); - background-color: var(--orange); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.enum-member::before { - -webkit-mask-image: url("images/intellisense/enum-member-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.struct::before { - -webkit-mask-image: url("images/intellisense/structure-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.event::before { - -webkit-mask-image: url("images/intellisense/event-alt1.svg"); - background-color: var(--orange); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.operator::before { - -webkit-mask-image: url("images/intellisense/operator-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.type-parameter::before { - -webkit-mask-image: url("images/intellisense/parameter-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.boolean::before, -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.null::before { - -webkit-mask-image: url("images/intellisense/boolean-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.class::before { - -webkit-mask-image: url("images/intellisense/class-alt1.svg"); - background-color: var(--orange); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.constructor::before, -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.method::before, -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.function::before { - -webkit-mask-image: url("images/intellisense/method-alt1.svg"); - background-color: var(--purple); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.file::before { - -webkit-mask-image: url("images/intellisense/file-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.field::before { - -webkit-mask-image: url("images/intellisense/field-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.variable::before { - -webkit-mask-image: url("images/intellisense/variable-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.array::before { - -webkit-mask-image: url("images/intellisense/array-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.keyword::before { - -webkit-mask-image: url("images/intellisense/keyword-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.interface::before { - -webkit-mask-image: url("images/intellisense/interface-alt1.svg"); - background-color: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.object::before, -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.namespace::before, -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.package::before, -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.module::before { - -webkit-mask-image: url("images/intellisense/namespace-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.number::before { - -webkit-mask-image: url("images/intellisense/numeric-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.property::before { - -webkit-mask-image: url("images/intellisense/property-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.string::before { - -webkit-mask-image: url("images/intellisense/key-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .symbol-icon.key::before { - -webkit-mask-image: url("images/intellisense/key-alt1.svg"); -} - -body[data-exploration^="icon-exploration"] .monaco-editor .lightbulb-glyph { - background-image: none !important; - -webkit-mask-repeat: no-repeat; - -webkit-mask-position: center center; - -webkit-mask-size: 16px; -} - -body[data-exploration="icon-exploration"] .monaco-editor .lightbulb-glyph, -body[data-exploration="icon-exploration"] .markers-panel .monaco-tl-contents .actions .action-label.icon.markers-panel-action-quickfix { - -webkit-mask-image: url("images/intellisense/lightbulb-alt1.svg"); - background-color: var(--yellow); -} - -body[data-exploration="icon-exploration"] .monaco-editor .lightbulb-glyph.autofixable, -body[data-exploration="icon-exploration"] .markers-panel .monaco-tl-contents .actions .action-label.icon.markers-panel-action-quickfix.autofixable { - -webkit-mask-image: url("images/intellisense/lightbulb-autofix-alt1.svg"); - background-color: var(--blue); -} - - -/**************** - Notifications -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon.icon-info, -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-title .severity-icon.severity-info, -body[data-exploration="icon-exploration"] .markers-panel .marker-icon.severity-info { - -webkit-mask-image: url("images/notifications/info-alt1.svg"); - background: var(--blue); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon.icon-warning, -body[data-exploration="icon-exploration"] .markers-panel .marker-icon.severity-warning, -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-title .severity-icon.severity-warning { - -webkit-mask-image: url("images/notifications/warning-alt1.svg"); - background: var(--yellow); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-icon.icon-error, -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-title .severity-icon.severity-error, -body[data-exploration="icon-exploration"] .markers-panel .marker-icon.severity-error { - -webkit-mask-image: url("images/notifications/error-alt1.svg"); - background: var(--redLight); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .clear-notification-action { - -webkit-mask-image: url("images/notifications/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action { - -webkit-mask-image: url("images/notifications/up-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action { - -webkit-mask-image: url("images/notifications/down-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action { - -webkit-mask-image: url("images/notifications/configure-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench > .notifications-center > .notifications-center-header .clear-all-notifications-action { - -webkit-mask-image: url("images/notifications/closeall-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench > .notifications-center > .notifications-center-header .hide-all-notifications-action { - -webkit-mask-image: url("images/notifications/down-alt1.svg"); -} - -body[data-exploration^="icon-exploration"] .markers-panel .monaco-tl-contents .marker-icon { - min-width: 16px; -} - - -/**************** - Tree -****************/ - -body[data-exploration^="icon-exploration"] .monaco-panel-view .panel > .panel-header::before { - position: absolute; - left: 2px; - top: 2px; -} - -body[data-exploration="icon-exploration"] .file-icon-themable-tree .monaco-tree-row.has-children.expanded .content::before, -body[data-exploration="icon-exploration"] .monaco-panel-view .panel > .panel-header.expanded::before, -body[data-exploration="icon-exploration"] .markers-panel .monaco-tl-contents .multiline-actions .action-label.octicon-chevron-up, -body[data-exploration="icon-exploration"] .monaco-tl-twistie.collapsible:not(.loading) { - -webkit-mask-image: url("images/tree/expand-alt1.svg"); - background-image: url("images/tree/expand-empty.svg") !important; -} - -body[data-exploration="icon-exploration"] .file-icon-themable-tree .monaco-tree-row.has-children .content::before, -body[data-exploration="icon-exploration"] .monaco-breadcrumbs .monaco-breadcrumb-item:not(:nth-child(2))::before, -body[data-exploration="icon-exploration"] .monaco-panel-view .panel > .panel-header::before, -body[data-exploration="icon-exploration"] .markers-panel .monaco-tl-contents .multiline-actions .action-label.octicon-chevron-down, -body[data-exploration="icon-exploration"] .monaco-tl-twistie.collapsible.collapsed:not(.loading) { - -webkit-mask-image: url("images/tree/collapse-alt1.svg"); - background-image: url("images/tree/expand-empty.svg") !important; - -} - -body[data-exploration="icon-exploration"] .customview-tree .monaco-tree .custom-view-tree-node-item > .custom-view-tree-node-item-resourceLabel > .actions .action-label[data-title="references-view.remove"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.closeActiveEditor"], -body[data-exploration="icon-exploration"] .monaco-editor .peekview-widget .head .peekview-actions .action-label.icon[data-title="peekview.close"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .close-editor-action, -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action:hover, -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .editor-group-container-toolbar .close-editor-group, -body[data-exploration="icon-exploration"] .monaco-workbench .explorer-viewlet .explorer-open-editors .close-editor-action { - -webkit-mask-image: url("images/tree/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty .close-editor-action, -body[data-exploration="icon-exploration"] .explorer-viewlet .explorer-open-editors .monaco-list .monaco-list-row.dirty:not(:hover) > .monaco-action-bar .close-editor-action { - -webkit-mask-image: url("images/tree/dirty-alt1.svg"); -} - - -/**************** - Tree -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="workbench.action.splitEditor"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.splitEditor"] { - -webkit-mask-image: url("images/editor/split-horizontal-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[title="Split Editor Down"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[title="Split Editor Down"] { - -webkit-mask-image: url("images/editor/split-vertical-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label > .actions .action-label[data-title="git.openChange"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .title-actions .action-label[data-title="git.openChange"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="git.openChange"] { - -webkit-mask-image: url("images/editor/open-change-alt1.svg"); -} - - -/**************** - Find -****************/ - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .previous::before { - -webkit-mask-image: url("images/find/previous-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .next::before { - -webkit-mask-image: url("images/find/next-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .close-fw::before { - -webkit-mask-image: url("images/find/close-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .monaco-checkbox .label::before { - -webkit-mask-image: url("images/find/selection-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .replace::before { - -webkit-mask-image: url("images/find/replace-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .replace-all::before { - -webkit-mask-image: url("images/find/replace-all-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .expand::before { - -webkit-mask-image: url("images/find/expand-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .collapse::before { - -webkit-mask-image: url("images/find/collapse-alt1.svg"); -} - -/**************** - Misc -****************/ - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="markdown.showPreviewToSide"]{ - -webkit-mask-image: url("images/misc/preview-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sizing-fit .monaco-icon-label.file-icon[title^="Preview"]::before{ - -webkit-mask-image: url("images/misc/preview-icon-alt1.svg"); - -webkit-mask-position: left center; -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="markdown.showSource"]{ - -webkit-mask-image: url("images/misc/gotofile-alt1.svg") -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="workbench.action.openGlobalKeybindingsFile"], -body[data-exploration="icon-exploration"] .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions .action-label[data-title="settings.switchToJSON"]{ - -webkit-mask-image: url("images/misc/json-alt1.svg") -} - -body[data-exploration^="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .monaco-custom-checkbox::before { - display: block; -} - -body[data-exploration="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .record-keys::before { - -webkit-mask-image: url("images/misc/keyboard-alt1.svg") -} - -body[data-exploration="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .clear-input { - -webkit-mask-image: url("images/misc/clear-alt1.svg") -} - -body[data-exploration="icon-exploration"] .keybindings-editor .monaco-action-bar .action-item > .sort-by-precedence::before { - -webkit-mask-image: url("images/misc/precedence-alt1.svg") -} - -body[data-exploration="icon-exploration"] .monaco-workbench .part.panel > .title > .panel-switcher-container.composite-bar > .monaco-action-bar .action-label.toggle-more { - -webkit-mask-image: url("images/misc/more-alt1.svg"); - background: var(--gray) !important; -} - -body[data-exploration^="icon-exploration"] .monaco-editor .margin-view-overlays .folding, -body[data-exploration^="icon-exploration"] .monaco-editor .margin-view-overlays .folding.collapsed { - -webkit-mask-position: 75% 50%; -} - -body[data-exploration="icon-exploration"] .monaco-editor .margin-view-overlays .folding { - -webkit-mask-image: url("images/misc/fold-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .margin-view-overlays .folding.collapsed { - -webkit-mask-image: url("images/misc/unfold-alt1.svg"); -} - -body[data-exploration="icon-exploration"] .monaco-editor .find-widget .matchesCount { - margin-right: 0; - padding-right: 0; -} - -body[data-exploration="icon-exploration"] .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked::before { - -webkit-mask-size: 14px; -} \ No newline at end of file diff --git a/src/vs/workbench/browser/media/images/activitybar/debug-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/debug-alt1.svg deleted file mode 100644 index 008fbc5070654..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/debug-alt1.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/extensions-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/extensions-alt1.svg deleted file mode 100644 index 0913a983e4efd..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/extensions-alt1.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/files-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/files-alt1.svg deleted file mode 100644 index 14c2bb322a808..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/files-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/git-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/git-alt1.svg deleted file mode 100644 index 33e120dd8bbcf..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/git-alt1.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/more-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/more-alt1.svg deleted file mode 100644 index 6729ca3c90d13..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/more-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/references-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/references-alt1.svg deleted file mode 100644 index 19bd140a92777..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/references-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/search-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/search-alt1.svg deleted file mode 100644 index 3a4852f756bbd..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/search-alt1.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/activitybar/settings-alt1.svg b/src/vs/workbench/browser/media/images/activitybar/settings-alt1.svg deleted file mode 100644 index a8213c3d01e7a..0000000000000 --- a/src/vs/workbench/browser/media/images/activitybar/settings-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/add-alt1.svg b/src/vs/workbench/browser/media/images/debug/add-alt1.svg deleted file mode 100644 index fb50c6c28499b..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/add-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-activate-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-activate-alt1.svg deleted file mode 100644 index 3e6b0a4c4df8c..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-activate-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-alt1.svg deleted file mode 100644 index e391c3b085275..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-conditional-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-conditional-alt1.svg deleted file mode 100644 index 9794d6b552259..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-conditional-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-function-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-function-alt1.svg deleted file mode 100644 index 76d1f05da2cc2..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-function-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-function-disabled-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-function-disabled-alt1.svg deleted file mode 100644 index 76d1f05da2cc2..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-function-disabled-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-function-unverified-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-function-unverified-alt1.svg deleted file mode 100644 index ece98d0f3561a..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-function-unverified-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-log-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-log-alt1.svg deleted file mode 100644 index 21ada7b292859..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-log-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-log-unverified-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-log-unverified-alt1.svg deleted file mode 100644 index f540bf94efb77..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-log-unverified-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/breakpoint-unverified-alt1.svg b/src/vs/workbench/browser/media/images/debug/breakpoint-unverified-alt1.svg deleted file mode 100644 index 6bfa8fd2f5a5b..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/breakpoint-unverified-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/close-alt1.svg b/src/vs/workbench/browser/media/images/debug/close-alt1.svg deleted file mode 100644 index 8af24a5b1e859..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/close-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/continue-alt1.svg b/src/vs/workbench/browser/media/images/debug/continue-alt1.svg deleted file mode 100644 index d9e1bcfa25dd1..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/continue-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/debug/current-and-breakpoint-alt1.svg b/src/vs/workbench/browser/media/images/debug/current-and-breakpoint-alt1.svg deleted file mode 100644 index df3c2501a533c..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/current-and-breakpoint-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/debug/current-arrow-alt1.svg b/src/vs/workbench/browser/media/images/debug/current-arrow-alt1.svg deleted file mode 100644 index f62a9fb6db4fa..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/current-arrow-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/disconnect-alt1.svg b/src/vs/workbench/browser/media/images/debug/disconnect-alt1.svg deleted file mode 100644 index 71aae0dd887fc..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/disconnect-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/drag-alt1.svg b/src/vs/workbench/browser/media/images/debug/drag-alt1.svg deleted file mode 100644 index b6b93f31fdff7..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/drag-alt1.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/gear-alt1.svg b/src/vs/workbench/browser/media/images/debug/gear-alt1.svg deleted file mode 100644 index 7db1664af786e..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/gear-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/debug/pause-alt1.svg b/src/vs/workbench/browser/media/images/debug/pause-alt1.svg deleted file mode 100644 index 1050e04f2d9fb..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/pause-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/repl-alt1.svg b/src/vs/workbench/browser/media/images/debug/repl-alt1.svg deleted file mode 100644 index f13e57b89ac29..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/repl-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/restart-alt1.svg b/src/vs/workbench/browser/media/images/debug/restart-alt1.svg deleted file mode 100644 index 28c63aae4d930..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/restart-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/stackframe-and-breakpoint-alt1.svg b/src/vs/workbench/browser/media/images/debug/stackframe-and-breakpoint-alt1.svg deleted file mode 100644 index df3c2501a533c..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/stackframe-and-breakpoint-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/debug/stackframe-arrow-alt1.svg b/src/vs/workbench/browser/media/images/debug/stackframe-arrow-alt1.svg deleted file mode 100644 index f62a9fb6db4fa..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/stackframe-arrow-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/start-alt1.svg b/src/vs/workbench/browser/media/images/debug/start-alt1.svg deleted file mode 100644 index 30196ede1685c..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/start-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/debug/step-into-alt1.svg b/src/vs/workbench/browser/media/images/debug/step-into-alt1.svg deleted file mode 100644 index 2113d7b1987a9..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/step-into-alt1.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/step-out-alt1.svg b/src/vs/workbench/browser/media/images/debug/step-out-alt1.svg deleted file mode 100644 index 6724964aea158..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/step-out-alt1.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/step-over-alt1.svg b/src/vs/workbench/browser/media/images/debug/step-over-alt1.svg deleted file mode 100644 index f2454843ae530..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/step-over-alt1.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/debug/stop-alt1.svg b/src/vs/workbench/browser/media/images/debug/stop-alt1.svg deleted file mode 100644 index 4e348228b6195..0000000000000 --- a/src/vs/workbench/browser/media/images/debug/stop-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/editor/open-change-alt1.svg b/src/vs/workbench/browser/media/images/editor/open-change-alt1.svg deleted file mode 100644 index 0c8297f940b08..0000000000000 --- a/src/vs/workbench/browser/media/images/editor/open-change-alt1.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/editor/split-horizontal-alt1.svg b/src/vs/workbench/browser/media/images/editor/split-horizontal-alt1.svg deleted file mode 100644 index c92025ddd92fb..0000000000000 --- a/src/vs/workbench/browser/media/images/editor/split-horizontal-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/editor/split-vertical-alt1.svg b/src/vs/workbench/browser/media/images/editor/split-vertical-alt1.svg deleted file mode 100644 index f407c08fa3412..0000000000000 --- a/src/vs/workbench/browser/media/images/editor/split-vertical-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/explorer/add-file-alt1.svg b/src/vs/workbench/browser/media/images/explorer/add-file-alt1.svg deleted file mode 100644 index 138351f66b2e9..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/add-file-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/explorer/add-folder-alt1.svg b/src/vs/workbench/browser/media/images/explorer/add-folder-alt1.svg deleted file mode 100644 index 0f1a2bfb9ba9b..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/add-folder-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/explorer/close-alt1.svg b/src/vs/workbench/browser/media/images/explorer/close-alt1.svg deleted file mode 100644 index 8af24a5b1e859..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/close-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/explorer/collapse-alt1.svg b/src/vs/workbench/browser/media/images/explorer/collapse-alt1.svg deleted file mode 100644 index f2e0e5dd5f6e4..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/collapse-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/explorer/layout-alt1.svg b/src/vs/workbench/browser/media/images/explorer/layout-alt1.svg deleted file mode 100644 index 40c1b46b197f3..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/layout-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/explorer/more-alt1.svg b/src/vs/workbench/browser/media/images/explorer/more-alt1.svg deleted file mode 100644 index 3d7068f6b4cd1..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/more-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/explorer/refresh-alt1.svg b/src/vs/workbench/browser/media/images/explorer/refresh-alt1.svg deleted file mode 100644 index a940b8ef4a62b..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/refresh-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/explorer/save-alt1.svg b/src/vs/workbench/browser/media/images/explorer/save-alt1.svg deleted file mode 100644 index 5756795cb42f9..0000000000000 --- a/src/vs/workbench/browser/media/images/explorer/save-alt1.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/media/images/extensions/clear-alt1.svg b/src/vs/workbench/browser/media/images/extensions/clear-alt1.svg deleted file mode 100644 index 63be0fae21516..0000000000000 --- a/src/vs/workbench/browser/media/images/extensions/clear-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/extensions/download-alt1.svg b/src/vs/workbench/browser/media/images/extensions/download-alt1.svg deleted file mode 100644 index 211864d2c8b9a..0000000000000 --- a/src/vs/workbench/browser/media/images/extensions/download-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/extensions/gear-alt1.svg b/src/vs/workbench/browser/media/images/extensions/gear-alt1.svg deleted file mode 100644 index 7db1664af786e..0000000000000 --- a/src/vs/workbench/browser/media/images/extensions/gear-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/extensions/star-empty-alt1.svg b/src/vs/workbench/browser/media/images/extensions/star-empty-alt1.svg deleted file mode 100644 index a35ded971f76f..0000000000000 --- a/src/vs/workbench/browser/media/images/extensions/star-empty-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/extensions/star-full-alt1.svg b/src/vs/workbench/browser/media/images/extensions/star-full-alt1.svg deleted file mode 100644 index 2413e6ecb1f12..0000000000000 --- a/src/vs/workbench/browser/media/images/extensions/star-full-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/extensions/star-half-alt1.svg b/src/vs/workbench/browser/media/images/extensions/star-half-alt1.svg deleted file mode 100644 index 4e8dcd71f3bf7..0000000000000 --- a/src/vs/workbench/browser/media/images/extensions/star-half-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/find/close-alt1.svg b/src/vs/workbench/browser/media/images/find/close-alt1.svg deleted file mode 100644 index 2512e9d61aac7..0000000000000 --- a/src/vs/workbench/browser/media/images/find/close-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/find/collapse-alt1.svg b/src/vs/workbench/browser/media/images/find/collapse-alt1.svg deleted file mode 100644 index 6d01adc07ea1d..0000000000000 --- a/src/vs/workbench/browser/media/images/find/collapse-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/find/expand-alt1.svg b/src/vs/workbench/browser/media/images/find/expand-alt1.svg deleted file mode 100644 index a1a96a60926e6..0000000000000 --- a/src/vs/workbench/browser/media/images/find/expand-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/find/next-alt1.svg b/src/vs/workbench/browser/media/images/find/next-alt1.svg deleted file mode 100644 index d2660e6e90f97..0000000000000 --- a/src/vs/workbench/browser/media/images/find/next-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/find/previous-alt1.svg b/src/vs/workbench/browser/media/images/find/previous-alt1.svg deleted file mode 100644 index 6f8d0cbcb6df7..0000000000000 --- a/src/vs/workbench/browser/media/images/find/previous-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/find/replace-all-alt1.svg b/src/vs/workbench/browser/media/images/find/replace-all-alt1.svg deleted file mode 100644 index 66437cf4410e9..0000000000000 --- a/src/vs/workbench/browser/media/images/find/replace-all-alt1.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/find/replace-alt1.svg b/src/vs/workbench/browser/media/images/find/replace-alt1.svg deleted file mode 100644 index b599b6e5432e2..0000000000000 --- a/src/vs/workbench/browser/media/images/find/replace-alt1.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/media/images/find/selection-alt1.svg b/src/vs/workbench/browser/media/images/find/selection-alt1.svg deleted file mode 100644 index e0503a93a5157..0000000000000 --- a/src/vs/workbench/browser/media/images/find/selection-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/check-alt1.svg b/src/vs/workbench/browser/media/images/git/check-alt1.svg deleted file mode 100644 index a5597d7c40499..0000000000000 --- a/src/vs/workbench/browser/media/images/git/check-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/clean-alt1.svg b/src/vs/workbench/browser/media/images/git/clean-alt1.svg deleted file mode 100644 index 2f3dd525c0d79..0000000000000 --- a/src/vs/workbench/browser/media/images/git/clean-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/close-alt1.svg b/src/vs/workbench/browser/media/images/git/close-alt1.svg deleted file mode 100644 index 64618b61760cc..0000000000000 --- a/src/vs/workbench/browser/media/images/git/close-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/git/gotofile-alt1.svg b/src/vs/workbench/browser/media/images/git/gotofile-alt1.svg deleted file mode 100644 index aabfc34c3e4a9..0000000000000 --- a/src/vs/workbench/browser/media/images/git/gotofile-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/git/initialze.svg b/src/vs/workbench/browser/media/images/git/initialze.svg deleted file mode 100644 index fb50c6c28499b..0000000000000 --- a/src/vs/workbench/browser/media/images/git/initialze.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/next-alt1.svg b/src/vs/workbench/browser/media/images/git/next-alt1.svg deleted file mode 100644 index d2660e6e90f97..0000000000000 --- a/src/vs/workbench/browser/media/images/git/next-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/previous-alt1.svg b/src/vs/workbench/browser/media/images/git/previous-alt1.svg deleted file mode 100644 index 6f8d0cbcb6df7..0000000000000 --- a/src/vs/workbench/browser/media/images/git/previous-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/refresh-alt1.svg b/src/vs/workbench/browser/media/images/git/refresh-alt1.svg deleted file mode 100644 index a940b8ef4a62b..0000000000000 --- a/src/vs/workbench/browser/media/images/git/refresh-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/stage-alt1.svg b/src/vs/workbench/browser/media/images/git/stage-alt1.svg deleted file mode 100644 index fb50c6c28499b..0000000000000 --- a/src/vs/workbench/browser/media/images/git/stage-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/git/unstage-alt1.svg b/src/vs/workbench/browser/media/images/git/unstage-alt1.svg deleted file mode 100644 index ae942eb674834..0000000000000 --- a/src/vs/workbench/browser/media/images/git/unstage-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/git/whitespace-alt1.svg b/src/vs/workbench/browser/media/images/git/whitespace-alt1.svg deleted file mode 100644 index b17a38ab079d4..0000000000000 --- a/src/vs/workbench/browser/media/images/git/whitespace-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/array-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/array-alt1.svg deleted file mode 100644 index b058a7ca9cc83..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/array-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/boolean-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/boolean-alt1.svg deleted file mode 100644 index 8fbcf89f2fdf4..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/boolean-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/class-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/class-alt1.svg deleted file mode 100644 index c939df47de56b..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/class-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/close-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/close-alt1.svg deleted file mode 100644 index 1d8840d92763d..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/close-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/color-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/color-alt1.svg deleted file mode 100644 index 914bb6f48d50f..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/color-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/constant-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/constant-alt1.svg deleted file mode 100644 index bbb9e6dcbf85d..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/constant-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/enum-member-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/enum-member-alt1.svg deleted file mode 100644 index e182868e71e5b..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/enum-member-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/enumerator-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/enumerator-alt1.svg deleted file mode 100644 index 7b87fce320237..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/enumerator-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/event-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/event-alt1.svg deleted file mode 100644 index 9c7c2504c249d..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/event-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/field-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/field-alt1.svg deleted file mode 100644 index e547fb51a2d86..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/field-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/file-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/file-alt1.svg deleted file mode 100644 index 9a0f5212ac708..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/file-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/folder-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/folder-alt1.svg deleted file mode 100644 index 8d3f68206e003..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/folder-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/info-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/info-alt1.svg deleted file mode 100644 index ef9fe8777a3f7..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/info-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/interface-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/interface-alt1.svg deleted file mode 100644 index 9114ce3f3e86e..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/interface-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/key-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/key-alt1.svg deleted file mode 100644 index 58c6cf4ca1151..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/key-alt1.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg deleted file mode 100644 index f21364efec0b1..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/keyword-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/lightbulb-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/lightbulb-alt1.svg deleted file mode 100644 index 1583a31632c9e..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/lightbulb-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/lightbulb-autofix-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/lightbulb-autofix-alt1.svg deleted file mode 100644 index d5ef68f9b83f5..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/lightbulb-autofix-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/method-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/method-alt1.svg deleted file mode 100644 index 392febfaa6b90..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/method-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/namespace-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/namespace-alt1.svg deleted file mode 100644 index bb4c103c752ba..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/namespace-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/numeric-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/numeric-alt1.svg deleted file mode 100644 index 90cf05e747ae2..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/numeric-alt1.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/operator-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/operator-alt1.svg deleted file mode 100644 index 20f50387a69ac..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/operator-alt1.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/parameter-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/parameter-alt1.svg deleted file mode 100644 index 00198f67f4e57..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/parameter-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/property-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/property-alt1.svg deleted file mode 100644 index 828113202a986..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/property-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/reference-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/reference-alt1.svg deleted file mode 100644 index aabfc34c3e4a9..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/reference-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/ruler-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/ruler-alt1.svg deleted file mode 100644 index eec16f41fbf65..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/ruler-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/snippet-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/snippet-alt1.svg deleted file mode 100644 index ee82045f2ac2c..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/snippet-alt1.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/string-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/string-alt1.svg deleted file mode 100644 index 1aa09c086cbcf..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/string-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/structure-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/structure-alt1.svg deleted file mode 100644 index f0e857ed7ca46..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/structure-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/intellisense/variable-alt1.svg b/src/vs/workbench/browser/media/images/intellisense/variable-alt1.svg deleted file mode 100644 index 8cf0dbb7116da..0000000000000 --- a/src/vs/workbench/browser/media/images/intellisense/variable-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/misc/clear-alt1.svg b/src/vs/workbench/browser/media/images/misc/clear-alt1.svg deleted file mode 100644 index 0e624a231916f..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/clear-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/fold-alt1.svg b/src/vs/workbench/browser/media/images/misc/fold-alt1.svg deleted file mode 100644 index 69efb3e695783..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/fold-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/misc/gotofile-alt1.svg b/src/vs/workbench/browser/media/images/misc/gotofile-alt1.svg deleted file mode 100644 index aabfc34c3e4a9..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/gotofile-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/json-alt1.svg b/src/vs/workbench/browser/media/images/misc/json-alt1.svg deleted file mode 100644 index 9e8f99141fc6b..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/json-alt1.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/keyboard-alt1.svg b/src/vs/workbench/browser/media/images/misc/keyboard-alt1.svg deleted file mode 100644 index 6181acae7ef0c..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/keyboard-alt1.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/more-alt1.svg b/src/vs/workbench/browser/media/images/misc/more-alt1.svg deleted file mode 100644 index 3d7068f6b4cd1..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/more-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/precedence-alt1.svg b/src/vs/workbench/browser/media/images/misc/precedence-alt1.svg deleted file mode 100644 index 2609f1f40f906..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/precedence-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/preview-alt1.svg b/src/vs/workbench/browser/media/images/misc/preview-alt1.svg deleted file mode 100644 index 25bf0b58bb9f6..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/preview-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/misc/preview-icon-alt1.svg b/src/vs/workbench/browser/media/images/misc/preview-icon-alt1.svg deleted file mode 100644 index df907d5dd141e..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/preview-icon-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/misc/split-alt1.svg b/src/vs/workbench/browser/media/images/misc/split-alt1.svg deleted file mode 100644 index c92025ddd92fb..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/split-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/misc/unfold-alt1.svg b/src/vs/workbench/browser/media/images/misc/unfold-alt1.svg deleted file mode 100644 index bb57558f6087e..0000000000000 --- a/src/vs/workbench/browser/media/images/misc/unfold-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/notifications/close-alt1.svg b/src/vs/workbench/browser/media/images/notifications/close-alt1.svg deleted file mode 100644 index 64618b61760cc..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/close-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/notifications/closeall-alt1.svg b/src/vs/workbench/browser/media/images/notifications/closeall-alt1.svg deleted file mode 100644 index 72bf0a8b54a89..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/closeall-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/notifications/configure-alt1.svg b/src/vs/workbench/browser/media/images/notifications/configure-alt1.svg deleted file mode 100644 index 7db1664af786e..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/configure-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/notifications/down-alt1.svg b/src/vs/workbench/browser/media/images/notifications/down-alt1.svg deleted file mode 100644 index 7042b08fddf28..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/down-alt1.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/notifications/error-alt1.svg b/src/vs/workbench/browser/media/images/notifications/error-alt1.svg deleted file mode 100644 index e39bf5e0e4a44..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/error-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/notifications/info-alt1.svg b/src/vs/workbench/browser/media/images/notifications/info-alt1.svg deleted file mode 100644 index 4a597c7b804e1..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/info-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/notifications/up-alt1.svg b/src/vs/workbench/browser/media/images/notifications/up-alt1.svg deleted file mode 100644 index d5edcc4c30570..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/up-alt1.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/notifications/warning-alt1.svg b/src/vs/workbench/browser/media/images/notifications/warning-alt1.svg deleted file mode 100644 index 948c0b4decf76..0000000000000 --- a/src/vs/workbench/browser/media/images/notifications/warning-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/panel/add-alt1.svg b/src/vs/workbench/browser/media/images/panel/add-alt1.svg deleted file mode 100644 index fb50c6c28499b..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/add-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/panel/clear-alt1.svg b/src/vs/workbench/browser/media/images/panel/clear-alt1.svg deleted file mode 100644 index 63be0fae21516..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/clear-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/panel/close-all-alt1.svg b/src/vs/workbench/browser/media/images/panel/close-all-alt1.svg deleted file mode 100644 index 8af24a5b1e859..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/close-all-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/panel/close-alt1.svg b/src/vs/workbench/browser/media/images/panel/close-alt1.svg deleted file mode 100644 index 3818f7d53506b..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/close-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/panel/collapse-all-alt1.svg b/src/vs/workbench/browser/media/images/panel/collapse-all-alt1.svg deleted file mode 100644 index f2e0e5dd5f6e4..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/collapse-all-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/panel/down-alt1.svg b/src/vs/workbench/browser/media/images/panel/down-alt1.svg deleted file mode 100644 index de3313624a40c..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/down-alt1.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/panel/gear-alt1.svg b/src/vs/workbench/browser/media/images/panel/gear-alt1.svg deleted file mode 100644 index 7db1664af786e..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/gear-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/panel/gotofile-alt1.svg b/src/vs/workbench/browser/media/images/panel/gotofile-alt1.svg deleted file mode 100644 index aabfc34c3e4a9..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/gotofile-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/panel/kill-alt1.svg b/src/vs/workbench/browser/media/images/panel/kill-alt1.svg deleted file mode 100644 index bc448290732b5..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/kill-alt1.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/panel/output-lock-alt1.svg b/src/vs/workbench/browser/media/images/panel/output-lock-alt1.svg deleted file mode 100644 index 70d268965a0d6..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/output-lock-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/panel/output-unlock-alt1.svg b/src/vs/workbench/browser/media/images/panel/output-unlock-alt1.svg deleted file mode 100644 index cf8268d37d260..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/output-unlock-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/panel/split-horizontal-alt1.svg b/src/vs/workbench/browser/media/images/panel/split-horizontal-alt1.svg deleted file mode 100644 index c92025ddd92fb..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/split-horizontal-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/panel/split-vertical-alt1.svg b/src/vs/workbench/browser/media/images/panel/split-vertical-alt1.svg deleted file mode 100644 index f407c08fa3412..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/split-vertical-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/panel/up-alt1.svg b/src/vs/workbench/browser/media/images/panel/up-alt1.svg deleted file mode 100644 index e7ac370945fe4..0000000000000 --- a/src/vs/workbench/browser/media/images/panel/up-alt1.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/search/case-sensitive-alt1.svg b/src/vs/workbench/browser/media/images/search/case-sensitive-alt1.svg deleted file mode 100644 index 418172b68660a..0000000000000 --- a/src/vs/workbench/browser/media/images/search/case-sensitive-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/search/clear-alt1.svg b/src/vs/workbench/browser/media/images/search/clear-alt1.svg deleted file mode 100644 index 890a6cddaa1f6..0000000000000 --- a/src/vs/workbench/browser/media/images/search/clear-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/search/collapse-all-alt1.svg b/src/vs/workbench/browser/media/images/search/collapse-all-alt1.svg deleted file mode 100644 index f2e0e5dd5f6e4..0000000000000 --- a/src/vs/workbench/browser/media/images/search/collapse-all-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/search/collapse-alt1.svg b/src/vs/workbench/browser/media/images/search/collapse-alt1.svg deleted file mode 100644 index 829e53760f266..0000000000000 --- a/src/vs/workbench/browser/media/images/search/collapse-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/search/exclude-alt1.svg b/src/vs/workbench/browser/media/images/search/exclude-alt1.svg deleted file mode 100644 index 2257ec6dae9af..0000000000000 --- a/src/vs/workbench/browser/media/images/search/exclude-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/search/expand-alt1.svg b/src/vs/workbench/browser/media/images/search/expand-alt1.svg deleted file mode 100644 index a1085f2ad07cf..0000000000000 --- a/src/vs/workbench/browser/media/images/search/expand-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/search/more-alt1.svg b/src/vs/workbench/browser/media/images/search/more-alt1.svg deleted file mode 100644 index a83faaa6ffb52..0000000000000 --- a/src/vs/workbench/browser/media/images/search/more-alt1.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/vs/workbench/browser/media/images/search/refresh-alt1.svg b/src/vs/workbench/browser/media/images/search/refresh-alt1.svg deleted file mode 100644 index a940b8ef4a62b..0000000000000 --- a/src/vs/workbench/browser/media/images/search/refresh-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/search/regex-alt1.svg b/src/vs/workbench/browser/media/images/search/regex-alt1.svg deleted file mode 100644 index bffb311a5be8d..0000000000000 --- a/src/vs/workbench/browser/media/images/search/regex-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/search/remove-alt1.svg b/src/vs/workbench/browser/media/images/search/remove-alt1.svg deleted file mode 100644 index 64618b61760cc..0000000000000 --- a/src/vs/workbench/browser/media/images/search/remove-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/search/replace-all-alt1.svg b/src/vs/workbench/browser/media/images/search/replace-all-alt1.svg deleted file mode 100644 index 1ef9b63cd606d..0000000000000 --- a/src/vs/workbench/browser/media/images/search/replace-all-alt1.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/vs/workbench/browser/media/images/search/replace-alt1.svg b/src/vs/workbench/browser/media/images/search/replace-alt1.svg deleted file mode 100644 index 0979845e83696..0000000000000 --- a/src/vs/workbench/browser/media/images/search/replace-alt1.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/vs/workbench/browser/media/images/search/stop-alt1.svg b/src/vs/workbench/browser/media/images/search/stop-alt1.svg deleted file mode 100644 index 52f3aa26ce288..0000000000000 --- a/src/vs/workbench/browser/media/images/search/stop-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/search/whole-word-alt1.svg b/src/vs/workbench/browser/media/images/search/whole-word-alt1.svg deleted file mode 100644 index 8a18eed8deb8a..0000000000000 --- a/src/vs/workbench/browser/media/images/search/whole-word-alt1.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/vs/workbench/browser/media/images/tree/close-alt1.svg b/src/vs/workbench/browser/media/images/tree/close-alt1.svg deleted file mode 100644 index 3818f7d53506b..0000000000000 --- a/src/vs/workbench/browser/media/images/tree/close-alt1.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/vs/workbench/browser/media/images/tree/collapse-alt1.svg b/src/vs/workbench/browser/media/images/tree/collapse-alt1.svg deleted file mode 100644 index f6e6553774e74..0000000000000 --- a/src/vs/workbench/browser/media/images/tree/collapse-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/tree/dirty-alt1.svg b/src/vs/workbench/browser/media/images/tree/dirty-alt1.svg deleted file mode 100644 index e391c3b085275..0000000000000 --- a/src/vs/workbench/browser/media/images/tree/dirty-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/tree/expand-alt1.svg b/src/vs/workbench/browser/media/images/tree/expand-alt1.svg deleted file mode 100644 index a98a85b340edb..0000000000000 --- a/src/vs/workbench/browser/media/images/tree/expand-alt1.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/vs/workbench/browser/media/images/tree/expand-empty.svg b/src/vs/workbench/browser/media/images/tree/expand-empty.svg deleted file mode 100644 index 1a0e359a2610c..0000000000000 --- a/src/vs/workbench/browser/media/images/tree/expand-empty.svg +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/vs/workbench/browser/style.ts b/src/vs/workbench/browser/style.ts index 24bc347c337c5..8db78ac995360 100644 --- a/src/vs/workbench/browser/style.ts +++ b/src/vs/workbench/browser/style.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/style'; -import 'vs/css!./media/icons'; import { registerThemingParticipant, ITheme, ICssStyleCollector, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService'; import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry'; diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 5b46af70bad68..2b164102e23b4 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -180,12 +180,6 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'default': true, 'description': nls.localize('activityBarVisibility', "Controls the visibility of the activity bar in the workbench.") }, - // TODO @misolori remove before shipping stable - 'workbench.iconExploration.enabled': { - 'type': 'boolean', - 'default': false, - 'description': nls.localize('iconExplorationEnabled', "Controls the visibility of the icon exploration in the workbench.") - }, 'workbench.view.alwaysShowHeaderActions': { 'type': 'boolean', 'default': false, From 253927a18aac8e015e4c2e6d06c57e396ff990b3 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Thu, 20 Jun 2019 15:58:14 -0700 Subject: [PATCH 210/364] Move listener to window service. --- src/vs/workbench/browser/web.main.ts | 8 -------- src/vs/workbench/browser/web.simpleservices.ts | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index d33b249cc98f9..6f1954ba2520a 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -36,7 +36,6 @@ import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; import { ProductService } from 'vs/platform/product/browser/productService'; -import { setFullscreen } from 'vs/base/browser/browser'; class CodeRendererMain extends Disposable { @@ -64,13 +63,6 @@ class CodeRendererMain extends Disposable { // Layout this._register(addDisposableListener(window, EventType.RESIZE, () => this.workbench.layout())); - this._register(addDisposableListener(document, EventType.FULLSCREEN_CHANGE, () => { - if (document.fullscreenElement || (document).webkitFullscreenElement) { - setFullscreen(true); - } else { - setFullscreen(false); - } - })); // Resource Loading this._register(new WebResources(services.serviceCollection.get(IFileService))); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index fd3d7c637cc3a..cb1eb5999ed51 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -45,6 +45,7 @@ import { CommentingRanges } from 'vs/editor/common/modes'; import { Range } from 'vs/editor/common/core/range'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { addDisposableListener, EventType } from 'vs/base/browser/dom'; //#region Backup File @@ -724,7 +725,7 @@ registerSingleton(IURLService, SimpleURLService); //#region Window -export class SimpleWindowService implements IWindowService { +export class SimpleWindowService extends Disposable implements IWindowService { _serviceBrand: any; @@ -735,6 +736,18 @@ export class SimpleWindowService implements IWindowService { readonly windowId = 0; + constructor() { + super(); + + this._register(addDisposableListener(document, EventType.FULLSCREEN_CHANGE, () => { + if (document.fullscreenElement || (document).webkitFullscreenElement) { + browser.setFullscreen(true); + } else { + browser.setFullscreen(false); + } + })); + } + isFocused(): Promise { return Promise.resolve(this.hasFocus); } From f7930a5bbda44408ed8395eb4291125dcd224100 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Thu, 20 Jun 2019 17:01:04 -0700 Subject: [PATCH 211/364] Minimap: Render find match decorations, fixes #75216 --- .../browser/viewParts/minimap/minimap.ts | 105 +++++++++++++++++- src/vs/editor/common/model.ts | 32 +++++- src/vs/editor/common/model/textModel.ts | 26 ++++- .../common/standalone/standaloneEnums.ts | 7 ++ src/vs/editor/contrib/find/findDecorations.ts | 10 +- .../standalone/browser/standaloneEditor.ts | 1 + src/vs/monaco.d.ts | 32 +++++- 7 files changed, 195 insertions(+), 18 deletions(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 6dd6de4761347..fa023adedd5ab 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -23,9 +23,10 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMinimapCharRenderer'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; -import { ViewLineData } from 'vs/editor/common/viewModel/viewModel'; +import { ViewLineData, ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel'; import { scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { ModelDecorationMinimapOptions } from 'vs/editor/common/model/textModel'; function getMinimapLineHeight(renderMinimap: RenderMinimap): number { if (renderMinimap === RenderMinimap.Large) { @@ -335,10 +336,7 @@ class RenderData { * Check if the current RenderData matches accurately the new desired layout and no painting is needed. */ public linesEquals(layout: MinimapLayout): boolean { - if (this.renderedLayout.startLineNumber !== layout.startLineNumber) { - return false; - } - if (this.renderedLayout.endLineNumber !== layout.endLineNumber) { + if (!this.scrollEquals(layout)) { return false; } @@ -354,6 +352,14 @@ class RenderData { return true; } + /** + * Check if the current RenderData matches the new layout's scroll position + */ + public scrollEquals(layout: MinimapLayout): boolean { + return this.renderedLayout.startLineNumber === layout.startLineNumber + && this.renderedLayout.endLineNumber === layout.endLineNumber; + } + _get(): { imageData: ImageData; rendLineNumberStart: number; lines: MinimapLine[]; } { const tmp = this._renderedLines._get(); return { @@ -435,6 +441,7 @@ export class Minimap extends ViewPart { private readonly _domNode: FastDomNode; private readonly _shadow: FastDomNode; private readonly _canvas: FastDomNode; + private readonly _decorationsCanvas: FastDomNode; private readonly _slider: FastDomNode; private readonly _sliderHorizontal: FastDomNode; private readonly _tokensColorTracker: MinimapTokensColorTracker; @@ -444,6 +451,7 @@ export class Minimap extends ViewPart { private _options: MinimapOptions; private _lastRenderData: RenderData | null; + private _decorationsChanged: boolean = false; private _buffers: MinimapBuffers | null; constructor(context: ViewContext) { @@ -469,6 +477,12 @@ export class Minimap extends ViewPart { this._canvas.setLeft(0); this._domNode.appendChild(this._canvas); + this._decorationsCanvas = createFastDomNode(document.createElement('canvas')); + this._decorationsCanvas.setPosition('absolute'); + this._decorationsCanvas.setClassName('minimap-decorations-layer'); + this._decorationsCanvas.setLeft(0); + this._domNode.appendChild(this._decorationsCanvas); + this._slider = createFastDomNode(document.createElement('div')); this._slider.setPosition('absolute'); this._slider.setClassName('minimap-slider'); @@ -569,10 +583,17 @@ export class Minimap extends ViewPart { this._domNode.setWidth(this._options.minimapWidth); this._domNode.setHeight(this._options.minimapHeight); this._shadow.setHeight(this._options.minimapHeight); + this._canvas.setWidth(this._options.canvasOuterWidth); this._canvas.setHeight(this._options.canvasOuterHeight); this._canvas.domNode.width = this._options.canvasInnerWidth; this._canvas.domNode.height = this._options.canvasInnerHeight; + + this._decorationsCanvas.setWidth(this._options.canvasOuterWidth); + this._decorationsCanvas.setHeight(this._options.canvasOuterHeight); + this._decorationsCanvas.domNode.width = this._options.canvasInnerWidth; + this._decorationsCanvas.domNode.height = this._options.canvasInnerHeight; + this._slider.setWidth(this._options.minimapWidth); } @@ -647,6 +668,11 @@ export class Minimap extends ViewPart { return true; } + public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { + this._decorationsChanged = true; + return true; + } + // --- end event handlers public prepareRender(ctx: RenderingContext): void { @@ -689,9 +715,78 @@ export class Minimap extends ViewPart { this._sliderHorizontal.setTop(0); this._sliderHorizontal.setHeight(layout.sliderHeight); + this.renderDecorations(layout); this._lastRenderData = this.renderLines(layout); } + private renderDecorations(layout: MinimapLayout) { + const scrollHasChanged = this._lastRenderData && !this._lastRenderData.scrollEquals(layout); + if (scrollHasChanged || this._decorationsChanged) { + this._decorationsChanged = false; + const decorations = this._context.model.getDecorationsInViewport(new Range(layout.startLineNumber, 1, layout.endLineNumber, this._context.model.getLineMaxColumn(layout.endLineNumber))); + + const { renderMinimap, canvasInnerWidth, canvasInnerHeight } = this._options; + const lineHeight = getMinimapLineHeight(renderMinimap); + const characterWidth = getMinimapCharWidth(renderMinimap); + const tabSize = this._context.model.getOptions().tabSize; + const canvasContext = this._decorationsCanvas.domNode.getContext('2d')!; + + canvasContext.clearRect(0, 0, canvasInnerWidth, canvasInnerHeight); + + // If the minimap is rendered using blocks, text takes up half the line height + const lineHeightRatio = renderMinimap === RenderMinimap.LargeBlocks || renderMinimap === RenderMinimap.SmallBlocks ? 0.5 : 1; + const height = lineHeight * lineHeightRatio; + + for (let i = 0; i < decorations.length; i++) { + if (decorations[i].options.minimap) { + this.renderDecoration(canvasContext, decorations[i], layout, height, lineHeight, tabSize, characterWidth); + } + } + } + } + + private renderDecoration(canvasContext: CanvasRenderingContext2D, + decoration: ViewModelDecoration, + layout: MinimapLayout, + height: number, + lineHeight: number, + tabSize: number, + charWidth: number) { + const { startLineNumber, startColumn, endColumn } = decoration.range; + + const startIndex = startColumn - 1; + const endIndex = endColumn - 1; + + const y = (startLineNumber - layout.startLineNumber) * lineHeight; + + // Get the offset of the decoration in the line. Have to read line data to see how much space each character takes. + let x = 0; + let endPosition = 0; + const lineData = this._context.model.getLineContent(startLineNumber); + for (let i = 0; i < endIndex; i++) { + const charCode = lineData.charCodeAt(i); + const dx = charCode === CharCode.Tab + ? tabSize * charWidth + : strings.isFullWidthCharacter(charCode) + ? 2 * charWidth + : charWidth; + + if (i < startIndex) { + x += dx; + } + + endPosition += dx; + } + + const width = endPosition - x; + + const minimapOptions = decoration.options.minimap; + const decorationColor = minimapOptions.getColor(this._context.theme); + + canvasContext.fillStyle = decorationColor; + canvasContext.fillRect(x, y, width, height); + } + private renderLines(layout: MinimapLayout): RenderData { const renderMinimap = this._options.renderMinimap; const startLineNumber = layout.startLineNumber; diff --git a/src/vs/editor/common/model.ts b/src/vs/editor/common/model.ts index ebc34ca227f7c..d2fa60c5640af 100644 --- a/src/vs/editor/common/model.ts +++ b/src/vs/editor/common/model.ts @@ -26,25 +26,45 @@ export enum OverviewRulerLane { } /** - * Options for rendering a model decoration in the overview ruler. + * Position in the minimap to render the decoration. */ -export interface IModelDecorationOverviewRulerOptions { +export enum MinimapPosition { + Inline = 1 +} + +export interface IDecorationOptions { /** - * CSS color to render in the overview ruler. + * CSS color to render. * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ color: string | ThemeColor | undefined; /** - * CSS color to render in the overview ruler. + * CSS color to render. * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ darkColor?: string | ThemeColor; +} + +/** + * Options for rendering a model decoration in the overview ruler. + */ +export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { /** * The position in the overview ruler. */ position: OverviewRulerLane; } +/** + * Options for rendering a model decoration in the overview ruler. + */ +export interface IModelDecorationMinimapOptions extends IDecorationOptions { + /** + * The position in the overview ruler. + */ + position: MinimapPosition; +} + /** * Options for a model decoration. */ @@ -89,6 +109,10 @@ export interface IModelDecorationOptions { * If set, render this decoration in the overview ruler. */ overviewRuler?: IModelDecorationOverviewRulerOptions | null; + /** + * If set, render this decoration in the minimap. + */ + minimap?: IModelDecorationMinimapOptions | null; /** * If set, the decoration will be rendered in the glyph margin with this CSS class name. */ diff --git a/src/vs/editor/common/model/textModel.ts b/src/vs/editor/common/model/textModel.ts index 2a640ac9d0180..344613d09eb49 100644 --- a/src/vs/editor/common/model/textModel.ts +++ b/src/vs/editor/common/model/textModel.ts @@ -2823,16 +2823,14 @@ function cleanClassName(className: string): string { return className.replace(/[^a-z0-9\-_]/gi, ' '); } -export class ModelDecorationOverviewRulerOptions implements model.IModelDecorationOverviewRulerOptions { +class DecorationOptions implements model.IDecorationOptions { readonly color: string | ThemeColor; readonly darkColor: string | ThemeColor; - readonly position: model.OverviewRulerLane; private _resolvedColor: string | null; - constructor(options: model.IModelDecorationOverviewRulerOptions) { + constructor(options: model.IDecorationOptions) { this.color = options.color || strings.empty; this.darkColor = options.darkColor || strings.empty; - this.position = (typeof options.position === 'number' ? options.position : model.OverviewRulerLane.Center); this._resolvedColor = null; } @@ -2863,6 +2861,24 @@ export class ModelDecorationOverviewRulerOptions implements model.IModelDecorati } } +export class ModelDecorationOverviewRulerOptions extends DecorationOptions { + readonly position: model.OverviewRulerLane; + + constructor(options: model.IModelDecorationOverviewRulerOptions) { + super(options); + this.position = (typeof options.position === 'number' ? options.position : model.OverviewRulerLane.Center); + } +} + +export class ModelDecorationMinimapOptions extends DecorationOptions { + readonly position: model.MinimapPosition; + + constructor(options: model.IModelDecorationMinimapOptions) { + super(options); + this.position = options.position; + } +} + export class ModelDecorationOptions implements model.IModelDecorationOptions { public static EMPTY: ModelDecorationOptions; @@ -2884,6 +2900,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions { readonly showIfCollapsed: boolean; readonly collapseOnReplaceEdit: boolean; readonly overviewRuler: ModelDecorationOverviewRulerOptions | null; + readonly minimap: ModelDecorationMinimapOptions | null; readonly glyphMarginClassName: string | null; readonly linesDecorationsClassName: string | null; readonly marginClassName: string | null; @@ -2902,6 +2919,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions { this.showIfCollapsed = options.showIfCollapsed || false; this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false; this.overviewRuler = options.overviewRuler ? new ModelDecorationOverviewRulerOptions(options.overviewRuler) : null; + this.minimap = options.minimap ? new ModelDecorationMinimapOptions(options.minimap) : null; this.glyphMarginClassName = options.glyphMarginClassName ? cleanClassName(options.glyphMarginClassName) : null; this.linesDecorationsClassName = options.linesDecorationsClassName ? cleanClassName(options.linesDecorationsClassName) : null; this.marginClassName = options.marginClassName ? cleanClassName(options.marginClassName) : null; diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 113afbafc3410..df80861b2a8b4 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -228,6 +228,13 @@ export enum OverviewRulerLane { Full = 7 } +/** + * Position in the minimap to render the decoration. + */ +export enum MinimapPosition { + Inline = 1 +} + /** * End of line character preference. */ diff --git a/src/vs/editor/contrib/find/findDecorations.ts b/src/vs/editor/contrib/find/findDecorations.ts index bb115977387bd..49a5527fd552f 100644 --- a/src/vs/editor/contrib/find/findDecorations.ts +++ b/src/vs/editor/contrib/find/findDecorations.ts @@ -7,7 +7,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { FindMatch, IModelDecorationsChangeAccessor, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; +import { FindMatch, IModelDecorationsChangeAccessor, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness, MinimapPosition } from 'vs/editor/common/model'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; @@ -269,6 +269,10 @@ export class FindDecorations implements IDisposable { overviewRuler: { color: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center + }, + minimap: { + color: themeColorFromId(overviewRulerFindMatchForeground), + position: MinimapPosition.Inline } }); @@ -279,6 +283,10 @@ export class FindDecorations implements IDisposable { overviewRuler: { color: themeColorFromId(overviewRulerFindMatchForeground), position: OverviewRulerLane.Center + }, + minimap: { + color: themeColorFromId(overviewRulerFindMatchForeground), + position: MinimapPosition.Inline } }); diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index b09f41e79f17b..8750db8f94301 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -352,6 +352,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { ScrollbarVisibility: standaloneEnums.ScrollbarVisibility, WrappingIndent: standaloneEnums.WrappingIndent, OverviewRulerLane: standaloneEnums.OverviewRulerLane, + MinimapPosition: standaloneEnums.MinimapPosition, EndOfLinePreference: standaloneEnums.EndOfLinePreference, DefaultEndOfLine: standaloneEnums.DefaultEndOfLine, EndOfLineSequence: standaloneEnums.EndOfLineSequence, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 34e8a703be451..3b1c5237e8316 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -1180,25 +1180,45 @@ declare namespace monaco.editor { } /** - * Options for rendering a model decoration in the overview ruler. + * Position in the minimap to render the decoration. */ - export interface IModelDecorationOverviewRulerOptions { + export enum MinimapPosition { + Inline = 1 + } + + export interface IDecorationOptions { /** - * CSS color to render in the overview ruler. + * CSS color to render. * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ color: string | ThemeColor | undefined; /** - * CSS color to render in the overview ruler. + * CSS color to render. * e.g.: rgba(100, 100, 100, 0.5) or a color from the color registry */ darkColor?: string | ThemeColor; + } + + /** + * Options for rendering a model decoration in the overview ruler. + */ + export interface IModelDecorationOverviewRulerOptions extends IDecorationOptions { /** * The position in the overview ruler. */ position: OverviewRulerLane; } + /** + * Options for rendering a model decoration in the overview ruler. + */ + export interface IModelDecorationMinimapOptions extends IDecorationOptions { + /** + * The position in the overview ruler. + */ + position: MinimapPosition; + } + /** * Options for a model decoration. */ @@ -1233,6 +1253,10 @@ declare namespace monaco.editor { * If set, render this decoration in the overview ruler. */ overviewRuler?: IModelDecorationOverviewRulerOptions | null; + /** + * If set, render this decoration in the minimap. + */ + minimap?: IModelDecorationMinimapOptions | null; /** * If set, the decoration will be rendered in the glyph margin with this CSS class name. */ From 1c275b0ce45c4d3eb2f94e6eb7dfa0d7a101d5c8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 15:42:26 -0700 Subject: [PATCH 212/364] Fix `navigator.serviceWorker.ready` is a Promise, not a function --- src/vs/workbench/contrib/webview/browser/pre/host.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/host.js b/src/vs/workbench/contrib/webview/browser/pre/host.js index 71acbf4b8a311..c5eefcd981085 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/host.js +++ b/src/vs/workbench/contrib/webview/browser/pre/host.js @@ -57,7 +57,7 @@ // If we have the wrong version, try once to unregister and re-register return registration.unregister() .then(() => navigator.serviceWorker.register('service-worker.js')) - .then(navigator.serviceWorker.ready) + .then(() => navigator.serviceWorker.ready) .finally(resolveWorkerReady); } }; From 804a266e0c8383e51fd9294f585f185ace5a563f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 15:43:42 -0700 Subject: [PATCH 213/364] Use update instead of manually tring to re-register --- src/vs/workbench/contrib/webview/browser/pre/host.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/host.js b/src/vs/workbench/contrib/webview/browser/pre/host.js index c5eefcd981085..903bf54e1c780 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/host.js +++ b/src/vs/workbench/contrib/webview/browser/pre/host.js @@ -55,8 +55,7 @@ return resolveWorkerReady(); } else { // If we have the wrong version, try once to unregister and re-register - return registration.unregister() - .then(() => navigator.serviceWorker.register('service-worker.js')) + return registration.update() .then(() => navigator.serviceWorker.ready) .finally(resolveWorkerReady); } From 7e1f8d4f1d5b1952b4ffb797a36e0fdeb897e8be Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 15:52:34 -0700 Subject: [PATCH 214/364] Extract ITypeScript server interface --- .../src/tsServer/server.ts | 21 +++++++++++++++++-- .../src/typescriptServiceClient.ts | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 10a001d52c23e..125c541fe0f0d 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -109,7 +109,7 @@ export class TypeScriptServerSpawner { version: TypeScriptVersion, configuration: TypeScriptServiceConfiguration, pluginManager: PluginManager - ): TypeScriptServer { + ): ITypeScriptServer { const apiVersion = version.version || API.defaultVersion; const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(configuration, version, apiVersion, pluginManager); @@ -303,7 +303,24 @@ class ChildServerProcess implements ServerProcess { } } -export class TypeScriptServer extends Disposable { +export interface ITypeScriptServer { + readonly onEvent: vscode.Event; + readonly onExit: vscode.Event; + readonly onError: vscode.Event; + readonly onReaderError: vscode.Event; + + readonly tsServerLogFile: string | undefined; + + kill(): void; + + executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined; + + dispose(): void; +} + +export class TypeScriptServer extends Disposable implements ITypeScriptServer { private readonly _reader: Reader; private readonly _requestQueue = new RequestQueue(); private readonly _callbacks = new CallbackMap(); diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index b478e9ed0802b..2849cfcd01205 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -10,7 +10,7 @@ import * as nls from 'vscode-nls'; import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; import * as Proto from './protocol'; -import { TypeScriptServer, TypeScriptServerSpawner } from './tsServer/server'; +import { ITypeScriptServer, TypeScriptServerSpawner } from './tsServer/server'; import { ITypeScriptServiceClient, ServerResponse } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; @@ -46,7 +46,7 @@ namespace ServerState { export class Running { readonly type = Type.Running; constructor( - public readonly server: TypeScriptServer, + public readonly server: ITypeScriptServer, /** * API version obtained from the version picker after checking the corresponding path exists. From ccf4a04d5a227289ece5e502a16dcc135507f82c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 15:56:42 -0700 Subject: [PATCH 215/364] extract server error to own file --- .../src/tsServer/server.ts | 71 +------------------ .../src/tsServer/serverError.ts | 64 +++++++++++++++++ 2 files changed, 65 insertions(+), 70 deletions(-) create mode 100644 extensions/typescript-language-features/src/tsServer/serverError.ts diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 125c541fe0f0d..881e35b6ececf 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -18,82 +18,13 @@ import LogDirectoryProvider from '../utils/logDirectoryProvider'; import Logger from '../utils/logger'; import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider'; import { PluginManager } from '../utils/plugins'; -import { escapeRegExp } from '../utils/regexp'; import TelemetryReporter from '../utils/telemetry'; import Tracer from '../utils/tracer'; import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; import { Reader } from '../utils/wireProtocol'; import { CallbackMap } from './callbackMap'; import { RequestItem, RequestQueue, RequestQueueingType } from './requestQueue'; - -class TypeScriptServerError extends Error { - - public static create( - version: TypeScriptVersion, - response: Proto.Response, - ): TypeScriptServerError { - const parsedResult = TypeScriptServerError.parseErrorText(version, response); - return new TypeScriptServerError(version, response, - parsedResult ? parsedResult.message : undefined, - parsedResult ? parsedResult.stack : undefined); - } - - constructor( - version: TypeScriptVersion, - private readonly response: Proto.Response, - public readonly serverMessage: string | undefined, - public readonly serverStack: string | undefined, - ) { - super(`TypeScript Server Error (${version.versionString})\n${serverMessage}\n${serverStack}`); - } - - public get serverErrorText() { - return this.response.message; - } - - public get serverCommand() { - return this.response.command; - } - - /** - * Given a `errorText` from a tsserver request indicating failure in handling a request, - * prepares a payload for telemetry-logging. - */ - private static parseErrorText( - version: TypeScriptVersion, - response: Proto.Response, - ) { - const errorText = response.message; - if (errorText) { - const errorPrefix = 'Error processing request. '; - if (errorText.startsWith(errorPrefix)) { - const prefixFreeErrorText = errorText.substr(errorPrefix.length); - const newlineIndex = prefixFreeErrorText.indexOf('\n'); - if (newlineIndex >= 0) { - // Newline expected between message and stack. - return { - message: prefixFreeErrorText.substring(0, newlineIndex), - stack: TypeScriptServerError.normalizeMessageStack(version, prefixFreeErrorText.substring(newlineIndex + 1)) - }; - } - } - } - return undefined; - } - - /** - * Try to replace full TS Server paths with 'tsserver.js' so that we don't have to post process the data as much - */ - private static normalizeMessageStack( - version: TypeScriptVersion, - message: string | undefined, - ) { - if (!message) { - return ''; - } - return message.replace(new RegExp(`${escapeRegExp(version.path)}[/\\\\]tsserver.js:`, 'gi'), 'tsserver.js:'); - } -} +import { TypeScriptServerError } from './serverError'; export class TypeScriptServerSpawner { public constructor( diff --git a/extensions/typescript-language-features/src/tsServer/serverError.ts b/extensions/typescript-language-features/src/tsServer/serverError.ts new file mode 100644 index 0000000000000..062c82f1336ce --- /dev/null +++ b/extensions/typescript-language-features/src/tsServer/serverError.ts @@ -0,0 +1,64 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as Proto from '../protocol'; +import { escapeRegExp } from '../utils/regexp'; +import { TypeScriptVersion } from '../utils/versionProvider'; + +export class TypeScriptServerError extends Error { + public static create( + version: TypeScriptVersion, + response: Proto.Response + ): TypeScriptServerError { + const parsedResult = TypeScriptServerError.parseErrorText(version, response); + return new TypeScriptServerError(version, response, parsedResult ? parsedResult.message : undefined, parsedResult ? parsedResult.stack : undefined); + } + + private constructor( + version: TypeScriptVersion, + private readonly response: Proto.Response, + public readonly serverMessage: string | undefined, + public readonly serverStack: string | undefined + ) { + super(`TypeScript Server Error (${version.versionString})\n${serverMessage}\n${serverStack}`); + } + + public get serverErrorText() { return this.response.message; } + + public get serverCommand() { return this.response.command; } + + /** + * Given a `errorText` from a tsserver request indicating failure in handling a request, + * prepares a payload for telemetry-logging. + */ + private static parseErrorText(version: TypeScriptVersion, response: Proto.Response) { + const errorText = response.message; + if (errorText) { + const errorPrefix = 'Error processing request. '; + if (errorText.startsWith(errorPrefix)) { + const prefixFreeErrorText = errorText.substr(errorPrefix.length); + const newlineIndex = prefixFreeErrorText.indexOf('\n'); + if (newlineIndex >= 0) { + // Newline expected between message and stack. + return { + message: prefixFreeErrorText.substring(0, newlineIndex), + stack: TypeScriptServerError.normalizeMessageStack(version, prefixFreeErrorText.substring(newlineIndex + 1)) + }; + } + } + } + return undefined; + } + + /** + * Try to replace full TS Server paths with 'tsserver.js' so that we don't have to post process the data as much + */ + private static normalizeMessageStack(version: TypeScriptVersion, message: string | undefined) { + if (!message) { + return ''; + } + return message.replace(new RegExp(`${escapeRegExp(version.path)}[/\\\\]tsserver.js:`, 'gi'), 'tsserver.js:'); + } +} From 4a053c9d6d797b6c92dd3329b01eac5e608ab186 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 16:00:36 -0700 Subject: [PATCH 216/364] Extract server spanwer to own file --- .../src/tsServer/server.ts | 185 +---------------- .../src/tsServer/spanwer.ts | 195 ++++++++++++++++++ .../src/typescriptServiceClient.ts | 3 +- 3 files changed, 198 insertions(+), 185 deletions(-) create mode 100644 extensions/typescript-language-features/src/tsServer/spanwer.ts diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 881e35b6ececf..52534972f1b37 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -3,180 +3,20 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as child_process from 'child_process'; import * as fs from 'fs'; -import * as path from 'path'; import * as stream from 'stream'; import * as vscode from 'vscode'; import * as Proto from '../protocol'; import { ServerResponse } from '../typescriptService'; -import API from '../utils/api'; -import { TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration'; import { Disposable } from '../utils/dispose'; -import * as electron from '../utils/electron'; -import LogDirectoryProvider from '../utils/logDirectoryProvider'; -import Logger from '../utils/logger'; -import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider'; -import { PluginManager } from '../utils/plugins'; import TelemetryReporter from '../utils/telemetry'; import Tracer from '../utils/tracer'; -import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; +import { TypeScriptVersion } from '../utils/versionProvider'; import { Reader } from '../utils/wireProtocol'; import { CallbackMap } from './callbackMap'; import { RequestItem, RequestQueue, RequestQueueingType } from './requestQueue'; import { TypeScriptServerError } from './serverError'; -export class TypeScriptServerSpawner { - public constructor( - private readonly _versionProvider: TypeScriptVersionProvider, - private readonly _logDirectoryProvider: LogDirectoryProvider, - private readonly _pluginPathsProvider: TypeScriptPluginPathsProvider, - private readonly _logger: Logger, - private readonly _telemetryReporter: TelemetryReporter, - private readonly _tracer: Tracer, - ) { } - - public spawn( - version: TypeScriptVersion, - configuration: TypeScriptServiceConfiguration, - pluginManager: PluginManager - ): ITypeScriptServer { - const apiVersion = version.version || API.defaultVersion; - - const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(configuration, version, apiVersion, pluginManager); - - if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { - if (tsServerLogFile) { - this._logger.info(`TSServer log file: ${tsServerLogFile}`); - } else { - this._logger.error('Could not create TSServer log directory'); - } - } - - this._logger.info('Forking TSServer'); - const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions()); - this._logger.info('Started TSServer'); - - return new TypeScriptServer( - new ChildServerProcess(childProcess), - tsServerLogFile, - new PipeRequestCanceller(cancellationPipeName, this._tracer), - version, - this._telemetryReporter, - this._tracer); - } - - private getForkOptions() { - const debugPort = TypeScriptServerSpawner.getDebugPort(); - const tsServerForkOptions: electron.ForkOptions = { - execArgv: debugPort ? [`--inspect=${debugPort}`] : [], - }; - return tsServerForkOptions; - } - - private getTsServerArgs( - configuration: TypeScriptServiceConfiguration, - currentVersion: TypeScriptVersion, - apiVersion: API, - pluginManager: PluginManager, - ): { args: string[], cancellationPipeName: string | undefined, tsServerLogFile: string | undefined } { - const args: string[] = []; - let cancellationPipeName: string | undefined; - let tsServerLogFile: string | undefined; - - if (apiVersion.gte(API.v206)) { - if (apiVersion.gte(API.v250)) { - args.push('--useInferredProjectPerProjectRoot'); - } else { - args.push('--useSingleInferredProject'); - } - - if (configuration.disableAutomaticTypeAcquisition) { - args.push('--disableAutomaticTypingAcquisition'); - } - } - - if (apiVersion.gte(API.v208)) { - args.push('--enableTelemetry'); - } - - if (apiVersion.gte(API.v222)) { - cancellationPipeName = electron.getTempFile('tscancellation'); - args.push('--cancellationPipeName', cancellationPipeName + '*'); - } - - if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { - const logDir = this._logDirectoryProvider.getNewLogDirectory(); - if (logDir) { - tsServerLogFile = path.join(logDir, `tsserver.log`); - args.push('--logVerbosity', TsServerLogLevel.toString(configuration.tsServerLogLevel)); - args.push('--logFile', tsServerLogFile); - } - } - - if (apiVersion.gte(API.v230)) { - const pluginPaths = this._pluginPathsProvider.getPluginPaths(); - - if (pluginManager.plugins.length) { - args.push('--globalPlugins', pluginManager.plugins.map(x => x.name).join(',')); - - const isUsingBundledTypeScriptVersion = currentVersion.path === this._versionProvider.defaultVersion.path; - for (const plugin of pluginManager.plugins) { - if (isUsingBundledTypeScriptVersion || plugin.enableForWorkspaceTypeScriptVersions) { - pluginPaths.push(plugin.path); - } - } - } - - if (pluginPaths.length !== 0) { - args.push('--pluginProbeLocations', pluginPaths.join(',')); - } - } - - if (apiVersion.gte(API.v234)) { - if (configuration.npmLocation) { - args.push('--npmLocation', `"${configuration.npmLocation}"`); - } - } - - if (apiVersion.gte(API.v260)) { - args.push('--locale', TypeScriptServerSpawner.getTsLocale(configuration)); - } - - if (apiVersion.gte(API.v291)) { - args.push('--noGetErrOnBackgroundUpdate'); - } - - if (apiVersion.gte(API.v345)) { - args.push('--validateDefaultNpmLocation'); - } - - return { args, cancellationPipeName, tsServerLogFile }; - } - - private static getDebugPort(): number | undefined { - const value = process.env['TSS_DEBUG']; - if (value) { - const port = parseInt(value); - if (!isNaN(port)) { - return port; - } - } - return undefined; - } - - private static isLoggingEnabled(apiVersion: API, configuration: TypeScriptServiceConfiguration) { - return apiVersion.gte(API.v222) && - configuration.tsServerLogLevel !== TsServerLogLevel.Off; - } - - private static getTsLocale(configuration: TypeScriptServiceConfiguration): string { - return configuration.locale - ? configuration.locale - : vscode.env.language; - } -} - export interface OngoingRequestCanceller { tryCancelOngoingRequest(seq: number): boolean; } @@ -211,28 +51,6 @@ export interface ServerProcess { kill(): void; } -class ChildServerProcess implements ServerProcess { - - public constructor( - private readonly _process: child_process.ChildProcess, - ) { } - - get stdout(): stream.Readable { return this._process.stdout!; } - - write(serverRequest: Proto.Request): void { - this._process.stdin!.write(JSON.stringify(serverRequest) + '\r\n', 'utf8'); - } - - on(name: 'exit', handler: (code: number | null) => void): void; - on(name: 'error', handler: (error: Error) => void): void; - on(name: any, handler: any) { - this._process.on(name, handler); - } - - kill(): void { - this._process.kill(); - } -} export interface ITypeScriptServer { readonly onEvent: vscode.Event; @@ -476,4 +294,3 @@ function getQueueingType( } return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal; } - diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spanwer.ts new file mode 100644 index 0000000000000..be3cf5f410435 --- /dev/null +++ b/extensions/typescript-language-features/src/tsServer/spanwer.ts @@ -0,0 +1,195 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as child_process from 'child_process'; +import * as path from 'path'; +import * as stream from 'stream'; +import * as vscode from 'vscode'; +import * as Proto from '../protocol'; +import API from '../utils/api'; +import { TsServerLogLevel, TypeScriptServiceConfiguration } from '../utils/configuration'; +import * as electron from '../utils/electron'; +import LogDirectoryProvider from '../utils/logDirectoryProvider'; +import Logger from '../utils/logger'; +import { TypeScriptPluginPathsProvider } from '../utils/pluginPathsProvider'; +import { PluginManager } from '../utils/plugins'; +import TelemetryReporter from '../utils/telemetry'; +import Tracer from '../utils/tracer'; +import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; +import { ITypeScriptServer, ServerProcess, TypeScriptServer, PipeRequestCanceller } from './server'; + +export class TypeScriptServerSpawner { + public constructor( + private readonly _versionProvider: TypeScriptVersionProvider, + private readonly _logDirectoryProvider: LogDirectoryProvider, + private readonly _pluginPathsProvider: TypeScriptPluginPathsProvider, + private readonly _logger: Logger, + private readonly _telemetryReporter: TelemetryReporter, + private readonly _tracer: Tracer, + ) { } + + public spawn( + version: TypeScriptVersion, + configuration: TypeScriptServiceConfiguration, + pluginManager: PluginManager + ): ITypeScriptServer { + const apiVersion = version.version || API.defaultVersion; + + const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(configuration, version, apiVersion, pluginManager); + + if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { + if (tsServerLogFile) { + this._logger.info(`TSServer log file: ${tsServerLogFile}`); + } else { + this._logger.error('Could not create TSServer log directory'); + } + } + + this._logger.info('Forking TSServer'); + const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions()); + this._logger.info('Started TSServer'); + + return new TypeScriptServer( + new ChildServerProcess(childProcess), + tsServerLogFile, + new PipeRequestCanceller(cancellationPipeName, this._tracer), + version, + this._telemetryReporter, + this._tracer); + } + + private getForkOptions() { + const debugPort = TypeScriptServerSpawner.getDebugPort(); + const tsServerForkOptions: electron.ForkOptions = { + execArgv: debugPort ? [`--inspect=${debugPort}`] : [], + }; + return tsServerForkOptions; + } + + private getTsServerArgs( + configuration: TypeScriptServiceConfiguration, + currentVersion: TypeScriptVersion, + apiVersion: API, + pluginManager: PluginManager, + ): { args: string[], cancellationPipeName: string | undefined, tsServerLogFile: string | undefined } { + const args: string[] = []; + let cancellationPipeName: string | undefined; + let tsServerLogFile: string | undefined; + + if (apiVersion.gte(API.v206)) { + if (apiVersion.gte(API.v250)) { + args.push('--useInferredProjectPerProjectRoot'); + } else { + args.push('--useSingleInferredProject'); + } + + if (configuration.disableAutomaticTypeAcquisition) { + args.push('--disableAutomaticTypingAcquisition'); + } + } + + if (apiVersion.gte(API.v208)) { + args.push('--enableTelemetry'); + } + + if (apiVersion.gte(API.v222)) { + cancellationPipeName = electron.getTempFile('tscancellation'); + args.push('--cancellationPipeName', cancellationPipeName + '*'); + } + + if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { + const logDir = this._logDirectoryProvider.getNewLogDirectory(); + if (logDir) { + tsServerLogFile = path.join(logDir, `tsserver.log`); + args.push('--logVerbosity', TsServerLogLevel.toString(configuration.tsServerLogLevel)); + args.push('--logFile', tsServerLogFile); + } + } + + if (apiVersion.gte(API.v230)) { + const pluginPaths = this._pluginPathsProvider.getPluginPaths(); + + if (pluginManager.plugins.length) { + args.push('--globalPlugins', pluginManager.plugins.map(x => x.name).join(',')); + + const isUsingBundledTypeScriptVersion = currentVersion.path === this._versionProvider.defaultVersion.path; + for (const plugin of pluginManager.plugins) { + if (isUsingBundledTypeScriptVersion || plugin.enableForWorkspaceTypeScriptVersions) { + pluginPaths.push(plugin.path); + } + } + } + + if (pluginPaths.length !== 0) { + args.push('--pluginProbeLocations', pluginPaths.join(',')); + } + } + + if (apiVersion.gte(API.v234)) { + if (configuration.npmLocation) { + args.push('--npmLocation', `"${configuration.npmLocation}"`); + } + } + + if (apiVersion.gte(API.v260)) { + args.push('--locale', TypeScriptServerSpawner.getTsLocale(configuration)); + } + + if (apiVersion.gte(API.v291)) { + args.push('--noGetErrOnBackgroundUpdate'); + } + + if (apiVersion.gte(API.v345)) { + args.push('--validateDefaultNpmLocation'); + } + + return { args, cancellationPipeName, tsServerLogFile }; + } + + private static getDebugPort(): number | undefined { + const value = process.env['TSS_DEBUG']; + if (value) { + const port = parseInt(value); + if (!isNaN(port)) { + return port; + } + } + return undefined; + } + + private static isLoggingEnabled(apiVersion: API, configuration: TypeScriptServiceConfiguration) { + return apiVersion.gte(API.v222) && + configuration.tsServerLogLevel !== TsServerLogLevel.Off; + } + + private static getTsLocale(configuration: TypeScriptServiceConfiguration): string { + return configuration.locale + ? configuration.locale + : vscode.env.language; + } +} + +class ChildServerProcess implements ServerProcess { + + public constructor( + private readonly _process: child_process.ChildProcess, + ) { } + + get stdout(): stream.Readable { return this._process.stdout!; } + + write(serverRequest: Proto.Request): void { + this._process.stdin!.write(JSON.stringify(serverRequest) + '\r\n', 'utf8'); + } + + on(name: 'exit', handler: (code: number | null) => void): void; + on(name: 'error', handler: (error: Error) => void): void; + on(name: any, handler: any) { + this._process.on(name, handler); + } + + kill(): void { + this._process.kill(); + } +} \ No newline at end of file diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 2849cfcd01205..bccddbf16f9e5 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -10,7 +10,7 @@ import * as nls from 'vscode-nls'; import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; import * as Proto from './protocol'; -import { ITypeScriptServer, TypeScriptServerSpawner } from './tsServer/server'; +import { ITypeScriptServer } from './tsServer/server'; import { ITypeScriptServiceClient, ServerResponse } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; @@ -25,6 +25,7 @@ import Tracer from './utils/tracer'; import { inferredProjectConfig } from './utils/tsconfig'; import { TypeScriptVersionPicker } from './utils/versionPicker'; import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider'; +import { TypeScriptServerSpawner } from './tsServer/spanwer'; const localize = nls.loadMessageBundle(); From 45ea4703c2e395165694c73d91b13cbbc6ccb9f1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 16:02:46 -0700 Subject: [PATCH 217/364] Renames --- .../src/test/server.test.ts | 6 ++--- .../src/tsServer/server.ts | 25 +++++++++---------- .../src/tsServer/spanwer.ts | 6 ++--- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/extensions/typescript-language-features/src/test/server.test.ts b/extensions/typescript-language-features/src/test/server.test.ts index bd22203d8d36a..00a4ff6a25453 100644 --- a/extensions/typescript-language-features/src/test/server.test.ts +++ b/extensions/typescript-language-features/src/test/server.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import 'mocha'; import * as stream from 'stream'; -import { PipeRequestCanceller, ServerProcess, TypeScriptServer } from '../tsServer/server'; +import { PipeRequestCanceller, TsServerProcess, ProcessBasedTsServer } from '../tsServer/server'; import { nulToken } from '../utils/cancellation'; import Logger from '../utils/logger'; import TelemetryReporter from '../utils/telemetry'; @@ -19,7 +19,7 @@ const NoopTelemetryReporter = new class implements TelemetryReporter { dispose(): void { /* noop */ } }; -class FakeServerProcess implements ServerProcess { +class FakeServerProcess implements TsServerProcess { private readonly _out: stream.PassThrough; private readonly writeListeners = new Set<(data: Buffer) => void>(); @@ -62,7 +62,7 @@ suite('Server', () => { test('should send requests with increasing sequence numbers', async () => { const process = new FakeServerProcess(); - const server = new TypeScriptServer(process, undefined, new PipeRequestCanceller(undefined, tracer), undefined!, NoopTelemetryReporter, tracer); + const server = new ProcessBasedTsServer(process, undefined, new PipeRequestCanceller(undefined, tracer), undefined!, NoopTelemetryReporter, tracer); const onWrite1 = process.onWrite(); server.executeImpl('geterr', {}, { isAsync: false, token: nulToken, expectsResult: true }); diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 52534972f1b37..95cf37e3e5a30 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -41,17 +41,6 @@ export class PipeRequestCanceller implements OngoingRequestCanceller { } } -export interface ServerProcess { - readonly stdout: stream.Readable; - write(serverRequest: Proto.Request): void; - - on(name: 'exit', handler: (code: number | null) => void): void; - on(name: 'error', handler: (error: Error) => void): void; - - kill(): void; -} - - export interface ITypeScriptServer { readonly onEvent: vscode.Event; readonly onExit: vscode.Event; @@ -69,14 +58,24 @@ export interface ITypeScriptServer { dispose(): void; } -export class TypeScriptServer extends Disposable implements ITypeScriptServer { +export interface TsServerProcess { + readonly stdout: stream.Readable; + write(serverRequest: Proto.Request): void; + + on(name: 'exit', handler: (code: number | null) => void): void; + on(name: 'error', handler: (error: Error) => void): void; + + kill(): void; +} + +export class ProcessBasedTsServer extends Disposable implements ITypeScriptServer { private readonly _reader: Reader; private readonly _requestQueue = new RequestQueue(); private readonly _callbacks = new CallbackMap(); private readonly _pendingResponses = new Set(); constructor( - private readonly _process: ServerProcess, + private readonly _process: TsServerProcess, private readonly _tsServerLogFile: string | undefined, private readonly _requestCanceller: OngoingRequestCanceller, private readonly _version: TypeScriptVersion, diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spanwer.ts index be3cf5f410435..7f6589c563576 100644 --- a/extensions/typescript-language-features/src/tsServer/spanwer.ts +++ b/extensions/typescript-language-features/src/tsServer/spanwer.ts @@ -18,7 +18,7 @@ import { PluginManager } from '../utils/plugins'; import TelemetryReporter from '../utils/telemetry'; import Tracer from '../utils/tracer'; import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; -import { ITypeScriptServer, ServerProcess, TypeScriptServer, PipeRequestCanceller } from './server'; +import { ITypeScriptServer, TsServerProcess, ProcessBasedTsServer, PipeRequestCanceller } from './server'; export class TypeScriptServerSpawner { public constructor( @@ -51,7 +51,7 @@ export class TypeScriptServerSpawner { const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions()); this._logger.info('Started TSServer'); - return new TypeScriptServer( + return new ProcessBasedTsServer( new ChildServerProcess(childProcess), tsServerLogFile, new PipeRequestCanceller(cancellationPipeName, this._tracer), @@ -171,7 +171,7 @@ export class TypeScriptServerSpawner { } } -class ChildServerProcess implements ServerProcess { +class ChildServerProcess implements TsServerProcess { public constructor( private readonly _process: child_process.ChildProcess, From 8ec2559029b67f0bca38d6d894277f4e92cb690a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 16:04:03 -0700 Subject: [PATCH 218/364] Move getQueueingType into class --- .../src/tsServer/server.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 95cf37e3e5a30..906da1aa09ad6 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -199,7 +199,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe request, expectsResponse: executeInfo.expectsResult, isAsync: executeInfo.isAsync, - queueingType: getQueueingType(command, executeInfo.lowPriority) + queueingType: ProcessBasedTsServer.getQueueingType(command, executeInfo.lowPriority) }; let result: Promise> | undefined; if (executeInfo.expectsResult) { @@ -280,16 +280,17 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe this._pendingResponses.delete(seq); return callback; } -} -const fenceCommands = new Set(['change', 'close', 'open', 'updateOpen']); + private static readonly fenceCommands = new Set(['change', 'close', 'open', 'updateOpen']); -function getQueueingType( - command: string, - lowPriority?: boolean -): RequestQueueingType { - if (fenceCommands.has(command)) { - return RequestQueueingType.Fence; + private static getQueueingType( + command: string, + lowPriority?: boolean + ): RequestQueueingType { + if (ProcessBasedTsServer.fenceCommands.has(command)) { + return RequestQueueingType.Fence; + } + return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal; } - return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal; } + From 87b8402b5940e92cfcd5b5bc34b6524984f8a89c Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 17:04:04 -0700 Subject: [PATCH 219/364] Add experimental dual TS server Fixes #75866 --- .../typescript-language-features/package.json | 6 ++ .../package.nls.json | 1 + .../src/test/server.test.ts | 2 +- .../src/tsServer/server.ts | 84 +++++++++++++++---- .../src/tsServer/spanwer.ts | 39 +++++++-- .../src/typescriptService.ts | 36 +++++--- .../src/typescriptServiceClient.ts | 15 ++-- .../src/utils/tracer.ts | 20 ++--- 8 files changed, 152 insertions(+), 51 deletions(-) diff --git a/extensions/typescript-language-features/package.json b/extensions/typescript-language-features/package.json index 86f996d06496b..00c0445e730c8 100644 --- a/extensions/typescript-language-features/package.json +++ b/extensions/typescript-language-features/package.json @@ -591,6 +591,12 @@ "default": true, "description": "%configuration.surveys.enabled%", "scope": "window" + }, + "typescript.experimental.useSeparateSyntaxServer": { + "type": "boolean", + "default": false, + "description": "%configuration.experimental.useSeparateSyntaxServer%", + "scope": "window" } } }, diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 7e31edca47985..569685dec0dc0 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -49,6 +49,7 @@ "typescript.problemMatchers.tsc.label": "TypeScript problems", "typescript.problemMatchers.tscWatch.label": "TypeScript problems (watch mode)", "configuration.suggest.paths": "Enable/disable suggestions for paths in import statements and require calls.", + "configuration.experimental.useSeparateSyntaxServer": "Enable/disable spawning a separate TypeScript server that can more quickly respond to syntax related operations, such as calculating folding or computing document symbols. Note that you must restart the TypeScript server after changing this setting. Requires using TypeScript 3.4.0 or newer in the workspace.", "typescript.locale": "Sets the locale used to report JavaScript and TypeScript errors. Requires using TypeScript 2.6.0 or newer in the workspace. Default of `null` uses VS Code's locale.", "javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable `experimentalDecorators` for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.", "configuration.suggest.autoImports": "Enable/disable auto import suggestions. Requires using TypeScript 2.6.1 or newer in the workspace.", diff --git a/extensions/typescript-language-features/src/test/server.test.ts b/extensions/typescript-language-features/src/test/server.test.ts index 00a4ff6a25453..651967fc12c02 100644 --- a/extensions/typescript-language-features/src/test/server.test.ts +++ b/extensions/typescript-language-features/src/test/server.test.ts @@ -62,7 +62,7 @@ suite('Server', () => { test('should send requests with increasing sequence numbers', async () => { const process = new FakeServerProcess(); - const server = new ProcessBasedTsServer(process, undefined, new PipeRequestCanceller(undefined, tracer), undefined!, NoopTelemetryReporter, tracer); + const server = new ProcessBasedTsServer('semantic', process, undefined, new PipeRequestCanceller('semantic', undefined, tracer), undefined!, NoopTelemetryReporter, tracer); const onWrite1 = process.onWrite(); server.executeImpl('geterr', {}, { isAsync: false, token: nulToken, expectsResult: true }); diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 906da1aa09ad6..9a2132fa27e56 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -7,7 +7,7 @@ import * as fs from 'fs'; import * as stream from 'stream'; import * as vscode from 'vscode'; import * as Proto from '../protocol'; -import { ServerResponse } from '../typescriptService'; +import { ServerResponse, TypeScriptRequests } from '../typescriptService'; import { Disposable } from '../utils/dispose'; import TelemetryReporter from '../utils/telemetry'; import Tracer from '../utils/tracer'; @@ -23,6 +23,7 @@ export interface OngoingRequestCanceller { export class PipeRequestCanceller implements OngoingRequestCanceller { public constructor( + private readonly _serverId: string, private readonly _cancellationPipeName: string | undefined, private readonly _tracer: Tracer, ) { } @@ -31,7 +32,7 @@ export class PipeRequestCanceller implements OngoingRequestCanceller { if (!this._cancellationPipeName) { return false; } - this._tracer.logTrace(`TypeScript Server: trying to cancel ongoing request with sequence number ${seq}`); + this._tracer.logTrace(this._serverId, `TypeScript Server: trying to cancel ongoing request with sequence number ${seq}`); try { fs.writeFileSync(this._cancellationPipeName + seq, ''); } catch { @@ -51,9 +52,9 @@ export interface ITypeScriptServer { kill(): void; - executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined; + executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined; dispose(): void; } @@ -75,6 +76,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe private readonly _pendingResponses = new Set(); constructor( + private readonly _serverId: string, private readonly _process: TsServerProcess, private readonly _tsServerLogFile: string | undefined, private readonly _requestCanceller: OngoingRequestCanceller, @@ -136,11 +138,11 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe const seq = (event as Proto.RequestCompletedEvent).body.request_seq; const p = this._callbacks.fetch(seq); if (p) { - this._tracer.traceRequestCompleted('requestCompleted', seq, p.startTime); + this._tracer.traceRequestCompleted(this._serverId, 'requestCompleted', seq, p.startTime); p.onSuccess(undefined); } } else { - this._tracer.traceEvent(event); + this._tracer.traceEvent(this._serverId, event); this._onEvent.fire(event); } break; @@ -156,7 +158,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe private tryCancelRequest(seq: number, command: string): boolean { try { if (this._requestQueue.tryDeletePendingRequest(seq)) { - this._tracer.logTrace(`TypeScript Server: canceled request with sequence number ${seq}`); + this.logTrace(`Canceled request with sequence number ${seq}`); return true; } @@ -164,7 +166,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe return true; } - this._tracer.logTrace(`TypeScript Server: tried to cancel request with sequence number ${seq}. But request got already delivered.`); + this.logTrace(`Tried to cancel request with sequence number ${seq}. But request got already delivered.`); return false; } finally { const callback = this.fetchCallback(seq); @@ -180,7 +182,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe return; } - this._tracer.traceResponse(response, callback.startTime); + this._tracer.traceResponse(this._serverId, response, callback.startTime); if (response.success) { callback.onSuccess(response); } else if (response.message === 'No content available.') { @@ -191,9 +193,9 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe } } - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - public executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { const request = this._requestQueue.createRequest(command, args); const requestInfo: RequestItem = { request, @@ -255,7 +257,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe private sendRequest(requestItem: RequestItem): void { const serverRequest = requestItem.request; - this._tracer.traceRequest(serverRequest, requestItem.expectsResponse, this._requestQueue.length); + this._tracer.traceRequest(this._serverId, serverRequest, requestItem.expectsResponse, this._requestQueue.length); if (requestItem.expectsResponse && !requestItem.isAsync) { this._pendingResponses.add(requestItem.request.seq); @@ -281,6 +283,10 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe return callback; } + private logTrace(message: string) { + this._tracer.logTrace(this._serverId, message); + } + private static readonly fenceCommands = new Set(['change', 'close', 'open', 'updateOpen']); private static getQueueingType( @@ -294,3 +300,53 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe } } + +export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServer { + public constructor( + private readonly syntaxServer: ITypeScriptServer, + private readonly semanticServer: ITypeScriptServer, + ) { + super(); + + this._register(syntaxServer.onEvent(e => this._onEvent.fire(e))); + this._register(semanticServer.onEvent(e => this._onEvent.fire(e))); + + this._register(semanticServer.onExit(e => this._onExit.fire(e))); + this._register(semanticServer.onError(e => this._onError.fire(e))); + } + + private readonly _onEvent = this._register(new vscode.EventEmitter()); + public readonly onEvent = this._onEvent.event; + + private readonly _onExit = this._register(new vscode.EventEmitter()); + public readonly onExit = this._onExit.event; + + private readonly _onError = this._register(new vscode.EventEmitter()); + public readonly onError = this._onError.event; + + public get onReaderError() { return this.semanticServer.onReaderError; } + + public get tsServerLogFile() { return this.semanticServer.tsServerLogFile; } + + public kill(): void { + this.syntaxServer.kill(); + this.semanticServer.kill(); + } + + private static readonly syntaxCommands = new Set(['navtree', 'getOutliningSpans', 'jsxClosingTag', 'selectionRange']); + private static readonly sharedCommands = new Set(['change', 'close', 'open', 'updateOpen', 'configure', 'configurePlugin']); + + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + + if (SyntaxRoutingTsServer.syntaxCommands.has(command)) { + return this.syntaxServer.executeImpl(command, args, executeInfo); + } else if (SyntaxRoutingTsServer.sharedCommands.has(command)) { + this.syntaxServer.executeImpl(command, args, executeInfo); + return this.semanticServer.executeImpl(command, args, executeInfo); + } else { + return this.semanticServer.executeImpl(command, args, executeInfo); + } + } +} diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spanwer.ts index 7f6589c563576..1c78d71c87ecf 100644 --- a/extensions/typescript-language-features/src/tsServer/spanwer.ts +++ b/extensions/typescript-language-features/src/tsServer/spanwer.ts @@ -18,7 +18,7 @@ import { PluginManager } from '../utils/plugins'; import TelemetryReporter from '../utils/telemetry'; import Tracer from '../utils/tracer'; import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; -import { ITypeScriptServer, TsServerProcess, ProcessBasedTsServer, PipeRequestCanceller } from './server'; +import { ITypeScriptServer, PipeRequestCanceller, ProcessBasedTsServer, SyntaxRoutingTsServer, TsServerProcess } from './server'; export class TypeScriptServerSpawner { public constructor( @@ -34,6 +34,30 @@ export class TypeScriptServerSpawner { version: TypeScriptVersion, configuration: TypeScriptServiceConfiguration, pluginManager: PluginManager + ): ITypeScriptServer { + if (this.shouldUserSeparateSyntaxServer(version)) { + const syntaxServer = this.spawnProcessBasedTsServer('syntax', version, configuration, pluginManager, ['--syntaxOnly', '--disableAutomaticTypingAcquisition']); + const semanticServer = this.spawnProcessBasedTsServer('semantic', version, configuration, pluginManager, []); + return new SyntaxRoutingTsServer(syntaxServer, semanticServer); + } + + return this.spawnProcessBasedTsServer('main', version, configuration, pluginManager, []); + } + + private shouldUserSeparateSyntaxServer(version: TypeScriptVersion): boolean { + if (!version.version || version.version.lt(API.v340)) { + return false; + } + return vscode.workspace.getConfiguration('typescript') + .get('experimental.useSeparateSyntaxServer', false); + } + + private spawnProcessBasedTsServer( + serverId: string, + version: TypeScriptVersion, + configuration: TypeScriptServiceConfiguration, + pluginManager: PluginManager, + extraForkArgs: readonly string[], ): ITypeScriptServer { const apiVersion = version.version || API.defaultVersion; @@ -41,20 +65,21 @@ export class TypeScriptServerSpawner { if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { if (tsServerLogFile) { - this._logger.info(`TSServer log file: ${tsServerLogFile}`); + this._logger.info(`<${serverId}> Log file: ${tsServerLogFile}`); } else { - this._logger.error('Could not create TSServer log directory'); + this._logger.error(`<${serverId}> Could not create log directory`); } } - this._logger.info('Forking TSServer'); - const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions()); - this._logger.info('Started TSServer'); + this._logger.info(`<${serverId}> Forking...`); + const childProcess = electron.fork(version.tsServerPath, [...args, ...extraForkArgs], this.getForkOptions()); + this._logger.info(`<${serverId}> Starting...`); return new ProcessBasedTsServer( + serverId, new ChildServerProcess(childProcess), tsServerLogFile, - new PipeRequestCanceller(cancellationPipeName, this._tracer), + new PipeRequestCanceller(serverId, cancellationPipeName, this._tracer), version, this._telemetryReporter, this._tracer); diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 1156b79d268c0..537cb2a0e2e7d 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -26,7 +26,7 @@ export namespace ServerResponse { export type Response = T | Cancelled | typeof NoContent; } -export interface TypeScriptRequestTypes { +interface StandardTsServerRequests { 'applyCodeActionCommand': [Proto.ApplyCodeActionCommandRequestArgs, Proto.ApplyCodeActionCommandResponse]; 'completionEntryDetails': [Proto.CompletionDetailsRequestArgs, Proto.CompletionDetailsResponse]; 'completionInfo': [Proto.CompletionsRequestArgs, Proto.CompletionInfoResponse]; @@ -59,6 +59,22 @@ export interface TypeScriptRequestTypes { 'typeDefinition': [Proto.FileLocationRequestArgs, Proto.TypeDefinitionResponse]; } +interface NoResponseTsServerRequests { + 'open': [Proto.OpenRequestArgs, null]; + 'close': [Proto.FileRequestArgs]; + 'change': [Proto.ChangeRequestArgs, null]; + 'updateOpen': [Proto.UpdateOpenRequestArgs, null]; + 'compilerOptionsForInferredProjects': [Proto.SetCompilerOptionsForInferredProjectsArgs, null]; + 'reloadProjects': [null, null]; + 'configurePlugin': [Proto.ConfigurePluginRequest, Proto.ConfigurePluginResponse]; +} + +interface AsyncTsServerRequests { + 'geterr': [Proto.GeterrRequestArgs, Proto.Response]; +} + +export type TypeScriptRequests = StandardTsServerRequests & NoResponseTsServerRequests & AsyncTsServerRequests; + export interface ITypeScriptServiceClient { /** * Convert a resource (VS Code) to a normalized path (TypeScript). @@ -100,19 +116,17 @@ export interface ITypeScriptServiceClient { readonly logger: Logger; readonly bufferSyncSupport: BufferSyncSupport; - execute( + execute( command: K, - args: TypeScriptRequestTypes[K][0], + args: StandardTsServerRequests[K][0], token: vscode.CancellationToken, lowPriority?: boolean - ): Promise>; - - executeWithoutWaitingForResponse(command: 'open', args: Proto.OpenRequestArgs): void; - executeWithoutWaitingForResponse(command: 'close', args: Proto.FileRequestArgs): void; - executeWithoutWaitingForResponse(command: 'change', args: Proto.ChangeRequestArgs): void; - executeWithoutWaitingForResponse(command: 'updateOpen', args: Proto.UpdateOpenRequestArgs): void; - executeWithoutWaitingForResponse(command: 'compilerOptionsForInferredProjects', args: Proto.SetCompilerOptionsForInferredProjectsArgs): void; - executeWithoutWaitingForResponse(command: 'reloadProjects', args: null): void; + ): Promise>; + + executeWithoutWaitingForResponse( + command: K, + args: NoResponseTsServerRequests[K][0] + ): void; executeAsync(command: 'geterr', args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise>; diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index bccddbf16f9e5..07de35b4ba3aa 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -11,7 +11,7 @@ import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; import * as Proto from './protocol'; import { ITypeScriptServer } from './tsServer/server'; -import { ITypeScriptServiceClient, ServerResponse } from './typescriptService'; +import { ITypeScriptServiceClient, ServerResponse, TypeScriptRequests } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; import { Disposable } from './utils/dispose'; @@ -607,7 +607,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } - public execute(command: string, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise> { + public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise> { return this.executeImpl(command, args, { isAsync: false, token, @@ -616,7 +616,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } - public executeWithoutWaitingForResponse(command: string, args: any): void { + public executeWithoutWaitingForResponse(command: keyof TypeScriptRequests, args: any): void { this.executeImpl(command, args, { isAsync: false, token: undefined, @@ -624,7 +624,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } - public executeAsync(command: string, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise> { + public executeAsync(command: keyof TypeScriptRequests, args: Proto.GeterrRequestArgs, token: vscode.CancellationToken): Promise> { return this.executeImpl(command, args, { isAsync: true, token, @@ -632,9 +632,9 @@ export default class TypeScriptServiceClient extends Disposable implements IType }); } - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; - private executeImpl(command: string, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { + private executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; + private executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; + private executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { this.bufferSyncSupport.beforeCommand(command); const runningServerState = this.service(); return runningServerState.server.executeImpl(command, args, executeInfo); @@ -769,7 +769,6 @@ export default class TypeScriptServiceClient extends Disposable implements IType this.logTelemetry(telemetryData.telemetryEventName, properties); } - private configurePlugin(pluginName: string, configuration: {}): any { if (this.apiVersion.gte(API.v314)) { this.executeWithoutWaitingForResponse('configurePlugin', { pluginName, configuration }); diff --git a/extensions/typescript-language-features/src/utils/tracer.ts b/extensions/typescript-language-features/src/utils/tracer.ts index c80254c79a074..f7ca0d674e3e9 100644 --- a/extensions/typescript-language-features/src/utils/tracer.ts +++ b/extensions/typescript-language-features/src/utils/tracer.ts @@ -50,7 +50,7 @@ export default class Tracer { return result; } - public traceRequest(request: Proto.Request, responseExpected: boolean, queueLength: number): void { + public traceRequest(serverId: string, request: Proto.Request, responseExpected: boolean, queueLength: number): void { if (this.trace === Trace.Off) { return; } @@ -58,10 +58,10 @@ export default class Tracer { if (this.trace === Trace.Verbose && request.arguments) { data = `Arguments: ${JSON.stringify(request.arguments, null, 4)}`; } - this.logTrace(`Sending request: ${request.command} (${request.seq}). Response expected: ${responseExpected ? 'yes' : 'no'}. Current queue length: ${queueLength}`, data); + this.logTrace(serverId, `Sending request: ${request.command} (${request.seq}). Response expected: ${responseExpected ? 'yes' : 'no'}. Current queue length: ${queueLength}`, data); } - public traceResponse(response: Proto.Response, startTime: number): void { + public traceResponse(serverId: string, response: Proto.Response, startTime: number): void { if (this.trace === Trace.Off) { return; } @@ -69,17 +69,17 @@ export default class Tracer { if (this.trace === Trace.Verbose && response.body) { data = `Result: ${JSON.stringify(response.body, null, 4)}`; } - this.logTrace(`Response received: ${response.command} (${response.request_seq}). Request took ${Date.now() - startTime} ms. Success: ${response.success} ${!response.success ? '. Message: ' + response.message : ''}`, data); + this.logTrace(serverId, `Response received: ${response.command} (${response.request_seq}). Request took ${Date.now() - startTime} ms. Success: ${response.success} ${!response.success ? '. Message: ' + response.message : ''}`, data); } - public traceRequestCompleted(command: string, request_seq: number, startTime: number): any { + public traceRequestCompleted(serverId: string, command: string, request_seq: number, startTime: number): any { if (this.trace === Trace.Off) { return; } - this.logTrace(`Async response received: ${command} (${request_seq}). Request took ${Date.now() - startTime} ms.`); + this.logTrace(serverId, `Async response received: ${command} (${request_seq}). Request took ${Date.now() - startTime} ms.`); } - public traceEvent(event: Proto.Event): void { + public traceEvent(serverId: string, event: Proto.Event): void { if (this.trace === Trace.Off) { return; } @@ -87,12 +87,12 @@ export default class Tracer { if (this.trace === Trace.Verbose && event.body) { data = `Data: ${JSON.stringify(event.body, null, 4)}`; } - this.logTrace(`Event received: ${event.event} (${event.seq}).`, data); + this.logTrace(serverId, `Event received: ${event.event} (${event.seq}).`, data); } - public logTrace(message: string, data?: any): void { + public logTrace(serverId: string, message: string, data?: any): void { if (this.trace !== Trace.Off) { - this.logger.logLevel('Trace', message, data); + this.logger.logLevel('Trace', `<${serverId}> ${message}`, data); } } } \ No newline at end of file From b362e9b6cac5ccba9701a8e35ee97888aabb7ef7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 17:09:20 -0700 Subject: [PATCH 220/364] Enable "typescript.experimental.useSeparateSyntaxServer" for VS Code workspace --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 3fa04b1ee95d0..bde5d6325419d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -59,5 +59,6 @@ "git.ignoreLimitWarning": true, "remote.extensionKind": { "msjsdiag.debugger-for-chrome": "workspace" - } + }, + "typescript.experimental.useSeparateSyntaxServer": true } From c6fe867ade5927eadd6b865ea02bd081d31d341d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 20 Jun 2019 17:12:55 -0700 Subject: [PATCH 221/364] Remove trailing comma --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 597d73d3e5a68..eb6f6aabc3200 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -318,7 +318,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'default': 'default', 'scope': ConfigurationScope.APPLICATION, 'markdownDescription': nls.localize('openFoldersInNewWindow', "Controls whether folders should open in a new window or replace the last active window.\nNote that there can still be cases where this setting is ignored (e.g. when using the `--new-window` or `--reuse-window` command line option).") - }, + } } }); From 1958209dafdc3f6175f088b4aaf3fdb797b82189 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 17:57:09 -0700 Subject: [PATCH 222/364] Include server id in TS server errors --- .../typescript-language-features/src/tsServer/server.ts | 2 +- .../src/tsServer/serverError.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 9a2132fa27e56..4a19cde00e76d 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -189,7 +189,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe // Special case where response itself is successful but there is not any data to return. callback.onSuccess(ServerResponse.NoContent); } else { - callback.onError(TypeScriptServerError.create(this._version, response)); + callback.onError(TypeScriptServerError.create(this._serverId, this._version, response)); } } diff --git a/extensions/typescript-language-features/src/tsServer/serverError.ts b/extensions/typescript-language-features/src/tsServer/serverError.ts index 062c82f1336ce..cb5cb8035f1e4 100644 --- a/extensions/typescript-language-features/src/tsServer/serverError.ts +++ b/extensions/typescript-language-features/src/tsServer/serverError.ts @@ -9,20 +9,22 @@ import { TypeScriptVersion } from '../utils/versionProvider'; export class TypeScriptServerError extends Error { public static create( + serverId: string, version: TypeScriptVersion, response: Proto.Response ): TypeScriptServerError { const parsedResult = TypeScriptServerError.parseErrorText(version, response); - return new TypeScriptServerError(version, response, parsedResult ? parsedResult.message : undefined, parsedResult ? parsedResult.stack : undefined); + return new TypeScriptServerError(serverId, version, response, parsedResult ? parsedResult.message : undefined, parsedResult ? parsedResult.stack : undefined); } private constructor( + serverId: string, version: TypeScriptVersion, private readonly response: Proto.Response, public readonly serverMessage: string | undefined, public readonly serverStack: string | undefined ) { - super(`TypeScript Server Error (${version.versionString})\n${serverMessage}\n${serverStack}`); + super(`<${serverId}> TypeScript Server Error (${version.versionString})\n${serverMessage}\n${serverStack}`); } public get serverErrorText() { return this.response.message; } From ec191a08f47e9f46f24131c3e33d0a582d8f0d1f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 17:59:36 -0700 Subject: [PATCH 223/364] Make execute command a configuration object --- .../src/features/implementationsCodeLens.ts | 2 +- .../src/features/referencesCodeLens.ts | 2 +- .../typescript-language-features/src/typescriptService.ts | 6 +++++- .../src/typescriptServiceClient.ts | 6 +++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts index 63cfc6222d91c..c732ade52231e 100644 --- a/extensions/typescript-language-features/src/features/implementationsCodeLens.ts +++ b/extensions/typescript-language-features/src/features/implementationsCodeLens.ts @@ -26,7 +26,7 @@ export default class TypeScriptImplementationsCodeLensProvider extends TypeScrip const codeLens = inputCodeLens as ReferencesCodeLens; const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); - const response = await this.client.execute('implementation', args, token, /* lowPriority */ true); + const response = await this.client.execute('implementation', args, token, { lowPriority: true }); if (response.type !== 'response' || !response.body) { codeLens.command = response.type === 'cancelled' ? TypeScriptBaseCodeLensProvider.cancelledCommand diff --git a/extensions/typescript-language-features/src/features/referencesCodeLens.ts b/extensions/typescript-language-features/src/features/referencesCodeLens.ts index ff09a9a4346cf..65c2cd5eb7f4f 100644 --- a/extensions/typescript-language-features/src/features/referencesCodeLens.ts +++ b/extensions/typescript-language-features/src/features/referencesCodeLens.ts @@ -22,7 +22,7 @@ class TypeScriptReferencesCodeLensProvider extends TypeScriptBaseCodeLensProvide public async resolveCodeLens(inputCodeLens: vscode.CodeLens, token: vscode.CancellationToken): Promise { const codeLens = inputCodeLens as ReferencesCodeLens; const args = typeConverters.Position.toFileLocationRequestArgs(codeLens.file, codeLens.range.start); - const response = await this.client.execute('references', args, token, /* lowPriority */ true); + const response = await this.client.execute('references', args, token, { lowPriority: true }); if (response.type !== 'response' || !response.body) { codeLens.command = response.type === 'cancelled' ? TypeScriptBaseCodeLensProvider.cancelledCommand diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 537cb2a0e2e7d..ba396ad2fd23e 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -75,6 +75,10 @@ interface AsyncTsServerRequests { export type TypeScriptRequests = StandardTsServerRequests & NoResponseTsServerRequests & AsyncTsServerRequests; +export type ExecConfig = { + lowPriority?: boolean; +}; + export interface ITypeScriptServiceClient { /** * Convert a resource (VS Code) to a normalized path (TypeScript). @@ -120,7 +124,7 @@ export interface ITypeScriptServiceClient { command: K, args: StandardTsServerRequests[K][0], token: vscode.CancellationToken, - lowPriority?: boolean + config?: ExecConfig ): Promise>; executeWithoutWaitingForResponse( diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 07de35b4ba3aa..ca99e59509a6d 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -11,7 +11,7 @@ import BufferSyncSupport from './features/bufferSyncSupport'; import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics'; import * as Proto from './protocol'; import { ITypeScriptServer } from './tsServer/server'; -import { ITypeScriptServiceClient, ServerResponse, TypeScriptRequests } from './typescriptService'; +import { ITypeScriptServiceClient, ServerResponse, TypeScriptRequests, ExecConfig } from './typescriptService'; import API from './utils/api'; import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration'; import { Disposable } from './utils/dispose'; @@ -607,12 +607,12 @@ export default class TypeScriptServiceClient extends Disposable implements IType return undefined; } - public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, lowPriority?: boolean): Promise> { + public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, config?: ExecConfig): Promise> { return this.executeImpl(command, args, { isAsync: false, token, expectsResult: true, - lowPriority + lowPriority: config ? config.lowPriority : undefined }); } From 362ca1d638eef676dee8977af286ba782ec55f0b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 18:01:39 -0700 Subject: [PATCH 224/364] Also include format in the syntax commands --- .../src/tsServer/server.ts | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 4a19cde00e76d..9fbe7e80facca 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -333,18 +333,32 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ this.semanticServer.kill(); } - private static readonly syntaxCommands = new Set(['navtree', 'getOutliningSpans', 'jsxClosingTag', 'selectionRange']); - private static readonly sharedCommands = new Set(['change', 'close', 'open', 'updateOpen', 'configure', 'configurePlugin']); + private static readonly syntaxCommands = new Set([ + 'navtree', + 'getOutliningSpans', + 'jsxClosingTag', + 'selectionRange', + 'format', + 'formatonkey', + ]); + private static readonly sharedCommands = new Set([ + 'change', + 'close', + 'open', + 'updateOpen', + 'configure', + 'configurePlugin', + ]); public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: false, lowPriority?: boolean }): undefined; public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise>; public executeImpl(command: keyof TypeScriptRequests, args: any, executeInfo: { isAsync: boolean, token?: vscode.CancellationToken, expectsResult: boolean, lowPriority?: boolean }): Promise> | undefined { - if (SyntaxRoutingTsServer.syntaxCommands.has(command)) { return this.syntaxServer.executeImpl(command, args, executeInfo); } else if (SyntaxRoutingTsServer.sharedCommands.has(command)) { - this.syntaxServer.executeImpl(command, args, executeInfo); - return this.semanticServer.executeImpl(command, args, executeInfo); + // Dispatch to both server but only return from syntax one + this.semanticServer.executeImpl(command, args, executeInfo); + return this.syntaxServer.executeImpl(command, args, executeInfo); } else { return this.semanticServer.executeImpl(command, args, executeInfo); } From fd245fcda031687f58a5d8cd2cf3c70ca4e1ad9d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 18:13:06 -0700 Subject: [PATCH 225/364] Fix method name --- .../typescript-language-features/src/tsServer/spanwer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spanwer.ts index 1c78d71c87ecf..d2ffd68b24ba3 100644 --- a/extensions/typescript-language-features/src/tsServer/spanwer.ts +++ b/extensions/typescript-language-features/src/tsServer/spanwer.ts @@ -35,7 +35,7 @@ export class TypeScriptServerSpawner { configuration: TypeScriptServiceConfiguration, pluginManager: PluginManager ): ITypeScriptServer { - if (this.shouldUserSeparateSyntaxServer(version)) { + if (this.shouldUseSeparateSyntaxServer(version)) { const syntaxServer = this.spawnProcessBasedTsServer('syntax', version, configuration, pluginManager, ['--syntaxOnly', '--disableAutomaticTypingAcquisition']); const semanticServer = this.spawnProcessBasedTsServer('semantic', version, configuration, pluginManager, []); return new SyntaxRoutingTsServer(syntaxServer, semanticServer); @@ -44,7 +44,7 @@ export class TypeScriptServerSpawner { return this.spawnProcessBasedTsServer('main', version, configuration, pluginManager, []); } - private shouldUserSeparateSyntaxServer(version: TypeScriptVersion): boolean { + private shouldUseSeparateSyntaxServer(version: TypeScriptVersion): boolean { if (!version.version || version.version.lt(API.v340)) { return false; } From 5fc7a8c5c0534baf4f86471707158993e9af257e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 18:15:33 -0700 Subject: [PATCH 226/364] Renames --- .../src/tsServer/spanwer.ts | 12 ++++++------ .../src/typescriptServiceClient.ts | 4 ++-- .../src/utils/versionProvider.ts | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spanwer.ts index d2ffd68b24ba3..b0abc67e286a2 100644 --- a/extensions/typescript-language-features/src/tsServer/spanwer.ts +++ b/extensions/typescript-language-features/src/tsServer/spanwer.ts @@ -36,30 +36,30 @@ export class TypeScriptServerSpawner { pluginManager: PluginManager ): ITypeScriptServer { if (this.shouldUseSeparateSyntaxServer(version)) { - const syntaxServer = this.spawnProcessBasedTsServer('syntax', version, configuration, pluginManager, ['--syntaxOnly', '--disableAutomaticTypingAcquisition']); - const semanticServer = this.spawnProcessBasedTsServer('semantic', version, configuration, pluginManager, []); + const syntaxServer = this.spawnTsServer('syntax', version, configuration, pluginManager, ['--syntaxOnly', '--disableAutomaticTypingAcquisition']); + const semanticServer = this.spawnTsServer('semantic', version, configuration, pluginManager, []); return new SyntaxRoutingTsServer(syntaxServer, semanticServer); } - return this.spawnProcessBasedTsServer('main', version, configuration, pluginManager, []); + return this.spawnTsServer('main', version, configuration, pluginManager, []); } private shouldUseSeparateSyntaxServer(version: TypeScriptVersion): boolean { - if (!version.version || version.version.lt(API.v340)) { + if (!version.apiVersion || version.apiVersion.lt(API.v340)) { return false; } return vscode.workspace.getConfiguration('typescript') .get('experimental.useSeparateSyntaxServer', false); } - private spawnProcessBasedTsServer( + private spawnTsServer( serverId: string, version: TypeScriptVersion, configuration: TypeScriptServiceConfiguration, pluginManager: PluginManager, extraForkArgs: readonly string[], ): ITypeScriptServer { - const apiVersion = version.version || API.defaultVersion; + const apiVersion = version.apiVersion || API.defaultVersion; const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(configuration, version, apiVersion, pluginManager); diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index ca99e59509a6d..6285981756ac8 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -285,7 +285,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType currentVersion = this.versionPicker.currentVersion; } - const apiVersion = this.versionPicker.currentVersion.version || API.defaultVersion; + const apiVersion = this.versionPicker.currentVersion.apiVersion || API.defaultVersion; this.onDidChangeTypeScriptVersion(currentVersion); let mytoken = ++this.token; @@ -353,7 +353,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType handle.onEvent(event => this.dispatchEvent(event)); this._onReady!.resolve(); - this._onTsServerStarted.fire(currentVersion.version); + this._onTsServerStarted.fire(currentVersion.apiVersion); if (apiVersion.gte(API.v300)) { this.loadingIndicator.startedLoadingProject(undefined /* projectName */); diff --git a/extensions/typescript-language-features/src/utils/versionProvider.ts b/extensions/typescript-language-features/src/utils/versionProvider.ts index fcbee87bb1d65..901446130bd9c 100644 --- a/extensions/typescript-language-features/src/utils/versionProvider.ts +++ b/extensions/typescript-language-features/src/utils/versionProvider.ts @@ -27,10 +27,10 @@ export class TypeScriptVersion { } public get isValid(): boolean { - return this.version !== undefined; + return this.apiVersion !== undefined; } - public get version(): API | undefined { + public get apiVersion(): API | undefined { const version = this.getTypeScriptVersion(this.tsServerPath); if (version) { return version; @@ -46,7 +46,7 @@ export class TypeScriptVersion { } public get versionString(): string { - const version = this.version; + const version = this.apiVersion; return version ? version.versionString : localize( 'couldNotLoadTsVersion', 'Could not load the TypeScript version at this path'); } From ffecce0476c74bb8482e9ad95767faa8681cc9da Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Thu, 20 Jun 2019 18:25:12 -0700 Subject: [PATCH 227/364] Better encapsulate logic of spawning different server kinds --- .../src/tsServer/spanwer.ts | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spanwer.ts index b0abc67e286a2..a7be07a0806bb 100644 --- a/extensions/typescript-language-features/src/tsServer/spanwer.ts +++ b/extensions/typescript-language-features/src/tsServer/spanwer.ts @@ -20,6 +20,8 @@ import Tracer from '../utils/tracer'; import { TypeScriptVersion, TypeScriptVersionProvider } from '../utils/versionProvider'; import { ITypeScriptServer, PipeRequestCanceller, ProcessBasedTsServer, SyntaxRoutingTsServer, TsServerProcess } from './server'; +type ServerKind = 'main' | 'syntax' | 'semantic'; + export class TypeScriptServerSpawner { public constructor( private readonly _versionProvider: TypeScriptVersionProvider, @@ -36,12 +38,12 @@ export class TypeScriptServerSpawner { pluginManager: PluginManager ): ITypeScriptServer { if (this.shouldUseSeparateSyntaxServer(version)) { - const syntaxServer = this.spawnTsServer('syntax', version, configuration, pluginManager, ['--syntaxOnly', '--disableAutomaticTypingAcquisition']); - const semanticServer = this.spawnTsServer('semantic', version, configuration, pluginManager, []); + const syntaxServer = this.spawnTsServer('syntax', version, configuration, pluginManager); + const semanticServer = this.spawnTsServer('semantic', version, configuration, pluginManager); return new SyntaxRoutingTsServer(syntaxServer, semanticServer); } - return this.spawnTsServer('main', version, configuration, pluginManager, []); + return this.spawnTsServer('main', version, configuration, pluginManager); } private shouldUseSeparateSyntaxServer(version: TypeScriptVersion): boolean { @@ -53,40 +55,39 @@ export class TypeScriptServerSpawner { } private spawnTsServer( - serverId: string, + kind: ServerKind, version: TypeScriptVersion, configuration: TypeScriptServiceConfiguration, pluginManager: PluginManager, - extraForkArgs: readonly string[], ): ITypeScriptServer { const apiVersion = version.apiVersion || API.defaultVersion; - const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(configuration, version, apiVersion, pluginManager); + const { args, cancellationPipeName, tsServerLogFile } = this.getTsServerArgs(kind, configuration, version, apiVersion, pluginManager); if (TypeScriptServerSpawner.isLoggingEnabled(apiVersion, configuration)) { if (tsServerLogFile) { - this._logger.info(`<${serverId}> Log file: ${tsServerLogFile}`); + this._logger.info(`<${kind}> Log file: ${tsServerLogFile}`); } else { - this._logger.error(`<${serverId}> Could not create log directory`); + this._logger.error(`<${kind}> Could not create log directory`); } } - this._logger.info(`<${serverId}> Forking...`); - const childProcess = electron.fork(version.tsServerPath, [...args, ...extraForkArgs], this.getForkOptions()); - this._logger.info(`<${serverId}> Starting...`); + this._logger.info(`<${kind}> Forking...`); + const childProcess = electron.fork(version.tsServerPath, args, this.getForkOptions(kind)); + this._logger.info(`<${kind}> Starting...`); return new ProcessBasedTsServer( - serverId, + kind, new ChildServerProcess(childProcess), tsServerLogFile, - new PipeRequestCanceller(serverId, cancellationPipeName, this._tracer), + new PipeRequestCanceller(kind, cancellationPipeName, this._tracer), version, this._telemetryReporter, this._tracer); } - private getForkOptions() { - const debugPort = TypeScriptServerSpawner.getDebugPort(); + private getForkOptions(kind: ServerKind) { + const debugPort = TypeScriptServerSpawner.getDebugPort(kind); const tsServerForkOptions: electron.ForkOptions = { execArgv: debugPort ? [`--inspect=${debugPort}`] : [], }; @@ -94,6 +95,7 @@ export class TypeScriptServerSpawner { } private getTsServerArgs( + kind: ServerKind, configuration: TypeScriptServiceConfiguration, currentVersion: TypeScriptVersion, apiVersion: API, @@ -103,6 +105,10 @@ export class TypeScriptServerSpawner { let cancellationPipeName: string | undefined; let tsServerLogFile: string | undefined; + if (kind === 'syntax') { + args.push('--syntaxOnly'); + } + if (apiVersion.gte(API.v206)) { if (apiVersion.gte(API.v250)) { args.push('--useInferredProjectPerProjectRoot'); @@ -110,12 +116,12 @@ export class TypeScriptServerSpawner { args.push('--useSingleInferredProject'); } - if (configuration.disableAutomaticTypeAcquisition) { + if (configuration.disableAutomaticTypeAcquisition || kind === 'syntax') { args.push('--disableAutomaticTypingAcquisition'); } } - if (apiVersion.gte(API.v208)) { + if (apiVersion.gte(API.v208) && kind !== 'syntax') { args.push('--enableTelemetry'); } @@ -173,7 +179,11 @@ export class TypeScriptServerSpawner { return { args, cancellationPipeName, tsServerLogFile }; } - private static getDebugPort(): number | undefined { + private static getDebugPort(kind: ServerKind): number | undefined { + if (kind === 'syntax') { + // We typically only want to debug the main semantic server + return undefined; + } const value = process.env['TSS_DEBUG']; if (value) { const port = parseInt(value); From 9ff8ae037e8e6109d65e4b5e3eb3dc60cc187e21 Mon Sep 17 00:00:00 2001 From: SteVen Batten Date: Thu, 20 Jun 2019 19:46:25 -0700 Subject: [PATCH 228/364] some fixes for mac web --- src/vs/workbench/browser/layout.ts | 6 +++--- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index e06870b2bb791..0eb3ce21f209b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -9,7 +9,7 @@ import { EventType, addDisposableListener, addClass, removeClass, isAncestor, ge import { onDidChangeFullscreen, isFullscreen, getZoomFactor } from 'vs/base/browser/browser'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { Registry } from 'vs/platform/registry/common/platform'; -import { isWindows, isLinux, isMacintosh, isWeb } from 'vs/base/common/platform'; +import { isWindows, isLinux, isMacintosh, isWeb, isNative } from 'vs/base/common/platform'; import { pathsToEditors } from 'vs/workbench/common/editor'; import { SidebarPart } from 'vs/workbench/browser/parts/sidebar/sidebarPart'; import { PanelPart } from 'vs/workbench/browser/parts/panel/panelPart'; @@ -229,7 +229,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } // Menubar visibility changes - if ((isWindows || isLinux) && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { + if ((isWindows || isLinux || isWeb) && getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') { this._register(this.titleService.onMenubarVisibilityChange(visible => this.onMenubarToggled(visible))); } } @@ -535,7 +535,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi return false; } else if (!this.state.fullscreen) { return true; - } else if (isMacintosh) { + } else if (isMacintosh && isNative) { return false; } else if (this.state.menuBar.visibility === 'visible') { return true; diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index eb6f6aabc3200..d3e988fa21fb5 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -298,7 +298,7 @@ import { isMacintosh, isWindows, isLinux, isWeb } from 'vs/base/common/platform' 'default': true, 'scope': ConfigurationScope.APPLICATION, 'description': nls.localize('enableMenuBarMnemonics', "If enabled, the main menus can be opened via Alt-key shortcuts. Disabling mnemonics allows to bind these Alt-key shortcuts to editor commands instead."), - 'included': isWindows || isLinux || isWeb + 'included': isWindows || isLinux }, 'window.disableCustomMenuBarAltFocus': { 'type': 'boolean', From 1f82a5b025ae4ab25afd01661e845417c100bb87 Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Fri, 21 Jun 2019 14:26:09 +0800 Subject: [PATCH 229/364] New test runner API for #74555 --- .../api/node/extHostExtensionService.ts | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 69d976b10d014..90e59f4f24548 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -36,7 +36,11 @@ import { RemoteAuthorityResolverError, ExtensionExecutionContext, ExtensionKind import { IURITransformer } from 'vs/base/common/uriIpc'; interface ITestRunner { + // Old test runner spec, shipped in vscode/lib/testrunner run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; + + // New test runner spec + runTests(): Promise; } export interface IHostUtils { @@ -534,7 +538,26 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { requireError = error; } - // Execute the runner if it follows our spec + // Execute the runner following the new `runTests` spec + if (testRunner && typeof testRunner.runTests === 'function') { + return new Promise((c, e) => { + testRunner!.runTests() + .then((succeeded) => { + if (succeeded) { + c(undefined); + this._gracefulExit(0); + } else { + this._gracefulExit(1); + } + }) + .catch(err => { + e(err); + this._gracefulExit(1); + }); + }); + } + + // Execute the runner if it follows the old `run` spec if (testRunner && typeof testRunner.run === 'function') { return new Promise((c, e) => { testRunner!.run(extensionTestsPath, (error, failures) => { From e4ca6137b4aeae9d9e5fe719bfd117d13bcfa634 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 21 Jun 2019 09:21:40 +0200 Subject: [PATCH 230/364] update doc, #74188 --- src/vs/vscode.proposed.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 29764773871ac..0ac46132de54e 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -61,7 +61,7 @@ declare module 'vscode' { export namespace env { /** * The name of a remote. Defined by extensions, popular samples are `wsl` for the Windows - * Subsystem for Linux or `ssh` for remotes using a secure shell. + * Subsystem for Linux or `ssh-remote` for remotes using a secure shell. * * *Note* that the value is `undefined` when there is no remote extension host but that the * value is defined in all extension hosts (local and remote) in case a remote extension host From 3233601840681b63d68cf4d6920b0fcdef7dd182 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Fri, 21 Jun 2019 10:28:26 +0200 Subject: [PATCH 231/364] build: release only iff all builds succeed, introduce VSCODE_RELEASE env --- build/azure-pipelines/common/publish.ts | 15 +-- build/azure-pipelines/common/release.ts | 109 ++++++++++++++++++ build/azure-pipelines/common/sync-mooncake.ts | 5 - build/azure-pipelines/product-build.yml | 16 ++- build/azure-pipelines/release.yml | 22 ++++ 5 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 build/azure-pipelines/common/release.ts create mode 100644 build/azure-pipelines/release.yml diff --git a/build/azure-pipelines/common/publish.ts b/build/azure-pipelines/common/publish.ts index 724939da31885..62113c8f3b3e4 100644 --- a/build/azure-pipelines/common/publish.ts +++ b/build/azure-pipelines/common/publish.ts @@ -151,13 +151,6 @@ async function publish(commit: string, quality: string, platform: string, type: const queuedBy = process.env['BUILD_QUEUEDBY']!; const sourceBranch = process.env['BUILD_SOURCEBRANCH']!; - const isReleased = ( - // Insiders: nightly build from master - (quality === 'insider' && /^master$|^refs\/heads\/master$/.test(sourceBranch) && /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy)) || - - // Exploration: any build from electron-4.0.x branch - (quality === 'exploration' && /^electron-4.0.x$|^refs\/heads\/electron-4.0.x$/.test(sourceBranch)) - ); console.log('Publishing...'); console.log('Quality:', quality); @@ -167,7 +160,6 @@ async function publish(commit: string, quality: string, platform: string, type: console.log('Version:', version); console.log('Commit:', commit); console.log('Is Update:', isUpdate); - console.log('Is Released:', isReleased); console.log('File:', file); const stat = await new Promise((c, e) => fs.stat(file, (err, stat) => err ? e(err) : c(stat))); @@ -226,7 +218,7 @@ async function publish(commit: string, quality: string, platform: string, type: id: commit, timestamp: (new Date()).getTime(), version, - isReleased: config.frozen ? false : isReleased, + isReleased: false, sourceBranch, queuedBy, assets: [] as Array, @@ -245,11 +237,6 @@ async function publish(commit: string, quality: string, platform: string, type: } function main(): void { - if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) { - console.warn('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH'); - return; - } - const commit = process.env['BUILD_SOURCEVERSION']; if (!commit) { diff --git a/build/azure-pipelines/common/release.ts b/build/azure-pipelines/common/release.ts new file mode 100644 index 0000000000000..1220bd62e688d --- /dev/null +++ b/build/azure-pipelines/common/release.ts @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { DocumentClient } from 'documentdb'; + +interface Config { + id: string; + frozen: boolean; +} + +function createDefaultConfig(quality: string): Config { + return { + id: quality, + frozen: false + }; +} + +function getConfig(quality: string): Promise { + const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] }); + const collection = 'dbs/builds/colls/config'; + const query = { + query: `SELECT TOP 1 * FROM c WHERE c.id = @quality`, + parameters: [ + { name: '@quality', value: quality } + ] + }; + + return new Promise((c, e) => { + client.queryDocuments(collection, query).toArray((err, results) => { + if (err && err.code !== 409) { return e(err); } + + c(!results || results.length === 0 ? createDefaultConfig(quality) : results[0] as any as Config); + }); + }); +} + +function doRelease(commit: string, quality: string): Promise { + const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] }); + const collection = 'dbs/builds/colls/' + quality; + const query = { + query: 'SELECT TOP 1 * FROM c WHERE c.id = @id', + parameters: [{ name: '@id', value: commit }] + }; + + let updateTries = 0; + + function update(): Promise { + updateTries++; + + return new Promise((c, e) => { + client.queryDocuments(collection, query).toArray((err, results) => { + if (err) { return e(err); } + if (results.length !== 1) { return e(new Error('No documents')); } + + const release = results[0]; + release.isReleased = true; + + client.replaceDocument(release._self, release, err => { + if (err && err.code === 409 && updateTries < 5) { return c(update()); } + if (err) { return e(err); } + + console.log('Build successfully updated.'); + c(); + }); + }); + }); + } + + return update(); +} + +async function release(commit: string, quality: string): Promise { + const config = await getConfig(quality); + + console.log('Quality config:', config); + + if (config.frozen) { + console.log(`Skipping release because quality ${quality} is frozen.`); + return; + } + + await doRelease(commit, quality); +} + +function env(name: string): string { + const result = process.env[name]; + + if (!result) { + throw new Error(`Skipping release due to missing env: ${name}`); + } + + return result; +} + +async function main(): Promise { + const commit = env('BUILD_SOURCEVERSION'); + const quality = env('VSCODE_QUALITY'); + + await release(commit, quality); +} + +main().catch(err => { + console.error(err); + process.exit(1); +}); diff --git a/build/azure-pipelines/common/sync-mooncake.ts b/build/azure-pipelines/common/sync-mooncake.ts index af0db530683f5..1eac8f34e9226 100644 --- a/build/azure-pipelines/common/sync-mooncake.ts +++ b/build/azure-pipelines/common/sync-mooncake.ts @@ -153,11 +153,6 @@ async function sync(commit: string, quality: string): Promise { } function main(): void { - if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) { - error('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH'); - return; - } - const commit = process.env['BUILD_SOURCEVERSION']; if (!commit) { diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 25c572cfd5668..60d99b36ed4c3 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -78,8 +78,22 @@ jobs: steps: - template: darwin/product-build-darwin.yml +- job: Release + condition: and(succeeded(), or(eq(variables['VSCODE_RELEASE'], 'true'), and(eq(variables['VSCODE_QUALITY'], 'insider'), eq(variables['Build.Reason'], 'Schedule')), and(eq(variables['VSCODE_QUALITY'], 'exploration'), eq(variables['Build.SourceBranch'], 'refs/heads/electron-4.0.x')))) + pool: + vmImage: 'Ubuntu-16.04' + dependsOn: + - Windows + - Windows32 + - Linux + - LinuxSnap + - LinuxArmhf + - LinuxAlpine + - macOS + steps: + - template: release.yml + - job: Mooncake - timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' condition: true diff --git a/build/azure-pipelines/release.yml b/build/azure-pipelines/release.yml new file mode 100644 index 0000000000000..eee54a1d8b793 --- /dev/null +++ b/build/azure-pipelines/release.yml @@ -0,0 +1,22 @@ +steps: +- task: NodeTool@0 + inputs: + versionSpec: "10.x" + +- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.x" + +- task: AzureKeyVault@1 + displayName: 'Azure Key Vault: Get Secrets' + inputs: + azureSubscription: 'vscode-builds-subscription' + KeyVaultName: vscode + +- script: | + set -e + + (cd build ; yarn) + + AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ + node build/azure-pipelines/common/release.js From 44596ac959bea131144ca23fee9809f4cc69c899 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 21 Jun 2019 10:56:36 +0200 Subject: [PATCH 232/364] first version of vscode.workspace.fs --- .../singlefolder-tests/workspace.fs.test.ts | 119 ++++++++++++++++++ src/vs/vscode.proposed.d.ts | 21 ++++ .../api/browser/mainThreadFileSystem.ts | 54 +++++++- .../workbench/api/common/extHost.protocol.ts | 9 ++ .../workbench/api/common/extHostFileSystem.ts | 34 +++++ src/vs/workbench/api/node/extHost.api.impl.ts | 4 + 6 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts new file mode 100644 index 0000000000000..92fe43e125f34 --- /dev/null +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts @@ -0,0 +1,119 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import { join } from 'path'; + +suite('workspace-fs', () => { + + let root: vscode.Uri; + + suiteSetup(function () { + root = vscode.workspace.workspaceFolders![0]!.uri; + }); + + test('fs.stat', async function () { + const stat = await vscode.workspace.fs.stat(root); + assert.equal(stat.type, vscode.FileType.Directory); + + assert.equal(typeof stat.size, 'number'); + assert.equal(typeof stat.mtime, 'number'); + assert.equal(typeof stat.ctime, 'number'); + + + const entries = await vscode.workspace.fs.readDirectory(root); + assert.ok(entries.length > 0); + + // find far.js + const tuple = entries.find(tuple => tuple[0] === 'far.js')!; + assert.ok(tuple); + assert.equal(tuple[0], 'far.js'); + assert.equal(tuple[1], vscode.FileType.File); + }); + + test('fs.stat - bad scheme', async function () { + try { + await vscode.workspace.fs.stat(vscode.Uri.parse('foo:/bar/baz/test.txt')); + assert.ok(false); + } catch { + assert.ok(true); + } + }); + + test('fs.stat - missing file', async function () { + try { + await vscode.workspace.fs.stat(root.with({ path: root.path + '.bad' })); + assert.ok(false); + } catch (e) { + assert.ok(true); + } + }); + + test('fs.write/stat/delete', async function () { + + const uri = root.with({ path: join(root.path, 'new.file') }); + await vscode.workspace.fs.writeFile(uri, Buffer.from('HELLO')); + + const stat = await vscode.workspace.fs.stat(uri); + assert.equal(stat.type, vscode.FileType.File); + + await vscode.workspace.fs.delete(uri); + + try { + await vscode.workspace.fs.stat(uri); + assert.ok(false); + } catch { + assert.ok(true); + } + }); + + test('fs.delete folder', async function () { + + const folder = root.with({ path: join(root.path, 'folder') }); + const file = root.with({ path: join(root.path, 'folder/file') }); + + await vscode.workspace.fs.createDirectory(folder); + await vscode.workspace.fs.writeFile(file, Buffer.from('FOO')); + + await vscode.workspace.fs.stat(folder); + await vscode.workspace.fs.stat(file); + + // ensure non empty folder cannot be deleted + try { + await vscode.workspace.fs.delete(folder, { recursive: false }); + assert.ok(false); + } catch { + await vscode.workspace.fs.stat(folder); + await vscode.workspace.fs.stat(file); + } + + // ensure non empty folder cannot be deleted is DEFAULT + try { + await vscode.workspace.fs.delete(folder); // recursive: false as default + assert.ok(false); + } catch { + await vscode.workspace.fs.stat(folder); + await vscode.workspace.fs.stat(file); + } + + // delete non empty folder with recursive-flag + await vscode.workspace.fs.delete(folder, { recursive: true }); + + // esnure folder/file are gone + try { + await vscode.workspace.fs.stat(folder); + assert.ok(false); + } catch { + assert.ok(true); + } + try { + await vscode.workspace.fs.stat(file); + assert.ok(false); + } catch { + assert.ok(true); + } + }); +}); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0ac46132de54e..e2580b6749547 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1519,4 +1519,25 @@ declare module 'vscode' { } //#endregion + + + //#region Joh - read/write files of any scheme + + export interface FileSystem { + stat(uri: Uri): Thenable; + readDirectory(uri: Uri): Thenable<[string, FileType][]>; + createDirectory(uri: Uri): Thenable; + readFile(uri: Uri): Thenable; + writeFile(uri: Uri, content: Uint8Array, options?: { create: boolean, overwrite: boolean }): Thenable; + delete(uri: Uri, options?: { recursive: boolean }): Thenable; + rename(oldUri: Uri, newUri: Uri, options?: { overwrite: boolean }): Thenable; + copy(source: Uri, destination: Uri, options?: { overwrite: boolean }): Thenable; + } + + export namespace workspace { + + export const fs: FileSystem; + } + + //#endregion } diff --git a/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/src/vs/workbench/api/browser/mainThreadFileSystem.ts index 61871e2c39bd8..2f395fd03e4fe 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystem.ts @@ -5,8 +5,8 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions, FileOpenOptions } from 'vs/platform/files/common/files'; +import { URI, UriComponents } from 'vs/base/common/uri'; +import { FileWriteOptions, FileSystemProviderCapabilities, IFileChange, IFileService, IFileSystemProvider, IStat, IWatchOptions, FileType, FileOverwriteOptions, FileDeleteOptions, FileOpenOptions, IFileStat } from 'vs/platform/files/common/files'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { ExtHostContext, ExtHostFileSystemShape, IExtHostContext, IFileChangeDto, MainContext, MainThreadFileSystemShape } from '../common/extHost.protocol'; import { ResourceLabelFormatter, ILabelService } from 'vs/platform/label/common/label'; @@ -60,6 +60,56 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { } fileProvider.$onFileSystemChange(changes); } + + + // --- + + async $stat(uri: UriComponents): Promise { + const stat = await this._fileService.resolve(URI.revive(uri), { resolveMetadata: true }); + return { + ctime: 0, + mtime: stat.mtime, + size: stat.size, + type: MainThreadFileSystem._getFileType(stat) + }; + } + + async $readdir(uri: UriComponents): Promise<[string, FileType][]> { + const stat = await this._fileService.resolve(URI.revive(uri), { resolveMetadata: false }); + if (!stat.children) { + throw new Error('not a folder'); + } + return stat.children.map(child => [child.name, MainThreadFileSystem._getFileType(child)]); + } + + private static _getFileType(stat: IFileStat): FileType { + return (stat.isDirectory ? FileType.Directory : FileType.File) + (stat.isSymbolicLink ? FileType.SymbolicLink : 0); + } + + async $readFile(resource: UriComponents): Promise { + return (await this._fileService.readFile(URI.revive(resource))).value; + } + + async $writeFile(resource: UriComponents, content: VSBuffer, opts: FileWriteOptions): Promise { + //todo@joh honor opts + await this._fileService.writeFile(URI.revive(resource), content, {}); + } + + async $rename(resource: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { + this._fileService.move(URI.revive(resource), URI.revive(target), opts.overwrite); + } + + async $copy(resource: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { + this._fileService.copy(URI.revive(resource), URI.revive(target), opts.overwrite); + } + + async $mkdir(resource: UriComponents): Promise { + this._fileService.createFolder(URI.revive(resource)); + } + + async $delete(resource: UriComponents, opts: FileDeleteOptions): Promise { + this._fileService.del(URI.revive(resource), opts); + } } class RemoteFileSystemProvider implements IFileSystemProvider { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 58ec9762b80f0..3257cafa43547 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -592,6 +592,15 @@ export interface MainThreadFileSystemShape extends IDisposable { $registerResourceLabelFormatter(handle: number, formatter: ResourceLabelFormatter): void; $unregisterResourceLabelFormatter(handle: number): void; $onFileSystemChange(handle: number, resource: IFileChangeDto[]): void; + + $stat(uri: UriComponents): Promise; + $readdir(resource: UriComponents): Promise<[string, files.FileType][]>; + $readFile(resource: UriComponents): Promise; + $writeFile(resource: UriComponents, content: VSBuffer, opts: files.FileWriteOptions): Promise; + $rename(resource: UriComponents, target: UriComponents, opts: files.FileOverwriteOptions): Promise; + $copy(resource: UriComponents, target: UriComponents, opts: files.FileOverwriteOptions): Promise; + $mkdir(resource: UriComponents): Promise; + $delete(resource: UriComponents, opts: files.FileDeleteOptions): Promise; } export interface MainThreadSearchShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index da723e3d01b97..0159b6403ebba 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -104,6 +104,36 @@ class FsLinkProvider { } } +class ConsumerFileSystem implements vscode.FileSystem { + + constructor(private _proxy: MainThreadFileSystemShape) { } + + stat(uri: vscode.Uri): Promise { + return this._proxy.$stat(uri); + } + readDirectory(uri: vscode.Uri): Promise<[string, vscode.FileType][]> { + return this._proxy.$readdir(uri); + } + createDirectory(uri: vscode.Uri): Promise { + return this._proxy.$mkdir(uri); + } + async readFile(uri: vscode.Uri): Promise { + return (await this._proxy.$readFile(uri)).buffer; + } + writeFile(uri: vscode.Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; } = { create: true, overwrite: true }): Promise { + return this._proxy.$writeFile(uri, VSBuffer.wrap(content), options); + } + delete(uri: vscode.Uri, options: { recursive: boolean; } = { recursive: false }): Promise { + return this._proxy.$delete(uri, { ...options, useTrash: true }); //todo@joh useTrash + } + rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: { overwrite: boolean; } = { overwrite: false }): Promise { + return this._proxy.$rename(oldUri, newUri, options); + } + copy(source: vscode.Uri, destination: vscode.Uri, options: { overwrite: boolean } = { overwrite: false }): Promise { + return this._proxy.$copy(source, destination, options); + } +} + export class ExtHostFileSystem implements ExtHostFileSystemShape { private readonly _proxy: MainThreadFileSystemShape; @@ -115,6 +145,8 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { private _linkProviderRegistration: IDisposable; private _handlePool: number = 0; + readonly fileSystem: vscode.FileSystem; + constructor(mainContext: IMainContext, private _extHostLanguageFeatures: ExtHostLanguageFeatures) { this._proxy = mainContext.getProxy(MainContext.MainThreadFileSystem); this._usedSchemes.add(Schemas.file); @@ -127,6 +159,8 @@ export class ExtHostFileSystem implements ExtHostFileSystemShape { this._usedSchemes.add(Schemas.mailto); this._usedSchemes.add(Schemas.data); this._usedSchemes.add(Schemas.command); + + this.fileSystem = new ConsumerFileSystem(this._proxy); } dispose(): void { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 8818154961399..dd6c14f666b0b 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -673,6 +673,10 @@ export function createApiFactory( registerFileSystemProvider(scheme, provider, options) { return extHostFileSystem.registerFileSystemProvider(scheme, provider, options); }, + get fs() { + checkProposedApiEnabled(extension); + return extHostFileSystem.fileSystem; + }, registerFileSearchProvider: proposedApiFunction(extension, (scheme: string, provider: vscode.FileSearchProvider) => { return extHostSearch.registerFileSearchProvider(scheme, provider); }), From 293596c9af033f0f76ee55933e0a7dc143c1ba13 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 21 Jun 2019 11:12:14 +0200 Subject: [PATCH 233/364] :lipstick: --- src/vs/vscode.proposed.d.ts | 4 ++-- .../api/browser/mainThreadFileSystem.ts | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index e2580b6749547..f60ed7ca4bdfb 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1530,8 +1530,8 @@ declare module 'vscode' { readFile(uri: Uri): Thenable; writeFile(uri: Uri, content: Uint8Array, options?: { create: boolean, overwrite: boolean }): Thenable; delete(uri: Uri, options?: { recursive: boolean }): Thenable; - rename(oldUri: Uri, newUri: Uri, options?: { overwrite: boolean }): Thenable; - copy(source: Uri, destination: Uri, options?: { overwrite: boolean }): Thenable; + rename(source: Uri, target: Uri, options?: { overwrite: boolean }): Thenable; + copy(source: Uri, target: Uri, options?: { overwrite: boolean }): Thenable; } export namespace workspace { diff --git a/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/src/vs/workbench/api/browser/mainThreadFileSystem.ts index 2f395fd03e4fe..5a52faf060e53 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystem.ts @@ -86,29 +86,29 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { return (stat.isDirectory ? FileType.Directory : FileType.File) + (stat.isSymbolicLink ? FileType.SymbolicLink : 0); } - async $readFile(resource: UriComponents): Promise { - return (await this._fileService.readFile(URI.revive(resource))).value; + async $readFile(uri: UriComponents): Promise { + return (await this._fileService.readFile(URI.revive(uri))).value; } - async $writeFile(resource: UriComponents, content: VSBuffer, opts: FileWriteOptions): Promise { + async $writeFile(uri: UriComponents, content: VSBuffer, opts: FileWriteOptions): Promise { //todo@joh honor opts - await this._fileService.writeFile(URI.revive(resource), content, {}); + await this._fileService.writeFile(URI.revive(uri), content, {}); } - async $rename(resource: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { - this._fileService.move(URI.revive(resource), URI.revive(target), opts.overwrite); + async $rename(source: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { + this._fileService.move(URI.revive(source), URI.revive(target), opts.overwrite); } - async $copy(resource: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { - this._fileService.copy(URI.revive(resource), URI.revive(target), opts.overwrite); + async $copy(source: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { + this._fileService.copy(URI.revive(source), URI.revive(target), opts.overwrite); } - async $mkdir(resource: UriComponents): Promise { - this._fileService.createFolder(URI.revive(resource)); + async $mkdir(uri: UriComponents): Promise { + this._fileService.createFolder(URI.revive(uri)); } - async $delete(resource: UriComponents, opts: FileDeleteOptions): Promise { - this._fileService.del(URI.revive(resource), opts); + async $delete(uri: UriComponents, opts: FileDeleteOptions): Promise { + this._fileService.del(URI.revive(uri), opts); } } From 50fc8fd24293007f29ca47b490ee3b4a360be80a Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 21 Jun 2019 11:36:56 +0200 Subject: [PATCH 234/364] Tasks registration + the local ext host now has an autority Part of https://github.com/microsoft/vscode-remote-release/issues/757 --- src/vs/workbench/api/node/extHost.api.impl.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 8818154961399..f970b136e8041 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -125,7 +125,8 @@ export function createApiFactory( const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress))); const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, new ExtHostOutputService(LogOutputChannelFactory, initData.logsLocation, rpcProtocol)); rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage); - if (initData.remote.authority) { + + if (initData.remote.isRemote && initData.remote.authority) { extHostTask.registerTaskSystem(Schemas.vscodeRemote, { scheme: Schemas.vscodeRemote, authority: initData.remote.authority, From 648b2d5ddf0660a51ae2e4d83c059c7ea5635ba9 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 21 Jun 2019 11:38:55 +0200 Subject: [PATCH 235/364] Add platform override to getDefaultShellAndArgs in terminal Part of https://github.com/microsoft/vscode-remote-release/issues/757 --- .../contrib/tasks/browser/terminalTaskSystem.ts | 2 +- .../workbench/contrib/terminal/browser/terminal.ts | 4 ++-- .../electron-browser/terminalInstanceService.ts | 12 +++++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index a481fcc0f6965..38c4ba18efc77 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -778,7 +778,7 @@ export class TerminalTaskSystem implements ITaskSystem { let terminalName = this.createTerminalName(task); let originalCommand = task.command.name; if (isShellCommand) { - const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(); + const defaultConfig = await this.terminalInstanceService.getDefaultShellAndArgs(platform); shellLaunchConfig = { name: terminalName, executable: defaultConfig.shell, args: defaultConfig.args, waitOnExit }; let shellSpecified: boolean = false; let shellOptions: ShellConfiguration | undefined = task.command.options && task.command.options.shell; diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 312ea61b5d66e..c9e3bdb74a36f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -8,7 +8,7 @@ import { WebLinksAddon as XTermWebLinksAddon } from 'xterm-addon-web-links'; import { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import { ITerminalInstance, IWindowsShellHelper, ITerminalConfigHelper, ITerminalChildProcess, IShellLaunchConfig, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IProcessEnvironment } from 'vs/base/common/platform'; +import { IProcessEnvironment, Platform } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; export const ITerminalInstanceService = createDecorator('terminalInstanceService'); @@ -30,7 +30,7 @@ export interface ITerminalInstanceService { createWindowsShellHelper(shellProcessId: number, instance: ITerminalInstance, xterm: XTermTerminal): IWindowsShellHelper; createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean): ITerminalChildProcess; - getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }>; + getDefaultShellAndArgs(platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>; getMainProcessParentEnv(): Promise; } diff --git a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts index 7b3a08d19780a..d725545794de6 100644 --- a/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts +++ b/src/vs/workbench/contrib/terminal/electron-browser/terminalInstanceService.ts @@ -7,7 +7,7 @@ import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/ import { ITerminalInstance, IWindowsShellHelper, IShellLaunchConfig, ITerminalChildProcess, IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY } from 'vs/workbench/contrib/terminal/common/terminal'; import { WindowsShellHelper } from 'vs/workbench/contrib/terminal/node/windowsShellHelper'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IProcessEnvironment, isLinux, isMacintosh, isWindows, platform } from 'vs/base/common/platform'; +import { IProcessEnvironment, isLinux, isMacintosh, isWindows, platform, Platform } from 'vs/base/common/platform'; import { TerminalProcess } from 'vs/workbench/contrib/terminal/node/terminalProcess'; import { getSystemShell } from 'vs/workbench/contrib/terminal/node/terminal'; import { Terminal as XTermTerminal } from 'xterm'; @@ -68,18 +68,20 @@ export class TerminalInstanceService implements ITerminalInstanceService { return this._storageService.getBoolean(IS_WORKSPACE_SHELL_ALLOWED_STORAGE_KEY, StorageScope.WORKSPACE, false); } - public getDefaultShellAndArgs(): Promise<{ shell: string, args: string[] | string | undefined }> { + public getDefaultShellAndArgs(platformOverride: Platform = platform): Promise<{ shell: string, args: string[] | undefined }> { const isWorkspaceShellAllowed = this._isWorkspaceShellAllowed(); const shell = getDefaultShell( (key) => this._configurationService.inspect(key), isWorkspaceShellAllowed, - getSystemShell(platform), + getSystemShell(platformOverride), process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'), - process.env.windir + process.env.windir, + platformOverride ); const args = getDefaultShellArgs( (key) => this._configurationService.inspect(key), - isWorkspaceShellAllowed + isWorkspaceShellAllowed, + platformOverride ); return Promise.resolve({ shell, args }); } From 94e7cd9cb6908e054379835253f0c6c3cfc76427 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 21 Jun 2019 12:03:35 +0200 Subject: [PATCH 236/364] Ensure no trailing path separtor on URIs from file picker Part of #75847 --- src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index 73aa2adcd4e91..d40fb37930663 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -242,6 +242,9 @@ export class RemoteFileDialog { this.filePickBox.items = []; function doResolve(dialog: RemoteFileDialog, uri: URI | undefined) { + if (uri) { + uri = resources.removeTrailingPathSeparator(uri); + } resolve(uri); dialog.contextKey.set(false); dialog.filePickBox.dispose(); From 59e2699376ac8b065e0145d2b40c2011f85bcf7a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 21 Jun 2019 12:41:18 +0200 Subject: [PATCH 237/364] data tree view state should store scrollTop, #74410 --- src/vs/base/browser/ui/tree/dataTree.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/tree/dataTree.ts b/src/vs/base/browser/ui/tree/dataTree.ts index d2342d7e85be3..bb93ca31fad01 100644 --- a/src/vs/base/browser/ui/tree/dataTree.ts +++ b/src/vs/base/browser/ui/tree/dataTree.ts @@ -18,6 +18,7 @@ export interface IDataTreeViewState { readonly focus: string[]; readonly selection: string[]; readonly expanded: string[]; + readonly scrollTop: number; } export class DataTree extends AbstractTree { @@ -80,6 +81,10 @@ export class DataTree extends AbstractTree extends AbstractTree Date: Fri, 21 Jun 2019 12:54:56 +0200 Subject: [PATCH 238/364] fix #75564 --- .../parts/editor/breadcrumbsControl.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 6590a90c12c94..12d9ee5b662fe 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -609,6 +609,42 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ widget.focusPrev(); } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'breadcrumbs.focusNextWithPicker', + weight: KeybindingWeight.WorkbenchContrib + 1, + primary: KeyMod.CtrlCmd | KeyCode.RightArrow, + mac: { + primary: KeyMod.Alt | KeyCode.RightArrow, + }, + when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive, WorkbenchListFocusContextKey), + handler(accessor) { + const groups = accessor.get(IEditorGroupsService); + const breadcrumbs = accessor.get(IBreadcrumbsService); + const widget = breadcrumbs.getWidget(groups.activeGroup.id); + if (!widget) { + return; + } + widget.focusNext(); + } +}); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'breadcrumbs.focusPrevious', + weight: KeybindingWeight.WorkbenchContrib + 1, + primary: KeyMod.CtrlCmd | KeyCode.LeftArrow, + mac: { + primary: KeyMod.Alt | KeyCode.LeftArrow, + }, + when: ContextKeyExpr.and(BreadcrumbsControl.CK_BreadcrumbsVisible, BreadcrumbsControl.CK_BreadcrumbsActive, WorkbenchListFocusContextKey), + handler(accessor) { + const groups = accessor.get(IEditorGroupsService); + const breadcrumbs = accessor.get(IBreadcrumbsService); + const widget = breadcrumbs.getWidget(groups.activeGroup.id); + if (!widget) { + return; + } + widget.focusPrev(); + } +}); KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'breadcrumbs.selectFocused', weight: KeybindingWeight.WorkbenchContrib, From b40dbda0bdd89b34ddb3881f7fc0dce2d9e3ef4e Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Fri, 21 Jun 2019 13:01:01 +0200 Subject: [PATCH 239/364] Change promise structure of creating terminal in tasks Potential fix for #75774 --- .../tasks/browser/terminalTaskSystem.ts | 176 +++++++++--------- 1 file changed, 85 insertions(+), 91 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index a481fcc0f6965..a7cb73817bb63 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -513,69 +513,69 @@ export class TerminalTaskSystem implements ITaskSystem { let executedCommand: string | undefined = undefined; let error: TaskError | undefined = undefined; let promise: Promise | undefined = undefined; - let terminalPromise: Promise | undefined = undefined; if (task.configurationProperties.isBackground) { - terminalPromise = new Promise(async (resolveTerminal) => { - [terminal, executedCommand, error] = await this.createTerminal(task, resolver); - resolveTerminal(); - }); - promise = new Promise(async (resolve, reject) => { - const problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers); - let watchingProblemMatcher = new WatchingProblemCollector(problemMatchers, this.markerService, this.modelService, this.fileService); - let toDispose: IDisposable[] | undefined = []; - let eventCounter: number = 0; - toDispose.push(watchingProblemMatcher.onDidStateChange((event) => { - if (event.kind === ProblemCollectorEventKind.BackgroundProcessingBegins) { - eventCounter++; - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task)); - } else if (event.kind === ProblemCollectorEventKind.BackgroundProcessingEnds) { - eventCounter--; - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Inactive, task)); - if (eventCounter === 0) { - if ((watchingProblemMatcher.numberOfMatches > 0) && watchingProblemMatcher.maxMarkerSeverity && - (watchingProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error)) { - let reveal = task.command.presentation!.reveal; - let revealProblems = task.command.presentation!.revealProblems; - if (revealProblems === RevealProblemKind.OnProblem) { - this.panelService.openPanel(Constants.MARKERS_PANEL_ID, true); - } else if (reveal === RevealKind.Silent) { - this.terminalService.setActiveInstance(terminal!); - this.terminalService.showPanel(false); - } + const problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers); + let watchingProblemMatcher = new WatchingProblemCollector(problemMatchers, this.markerService, this.modelService, this.fileService); + let toDispose: IDisposable[] | undefined = []; + let eventCounter: number = 0; + toDispose.push(watchingProblemMatcher.onDidStateChange((event) => { + if (event.kind === ProblemCollectorEventKind.BackgroundProcessingBegins) { + eventCounter++; + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task)); + } else if (event.kind === ProblemCollectorEventKind.BackgroundProcessingEnds) { + eventCounter--; + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Inactive, task)); + if (eventCounter === 0) { + if ((watchingProblemMatcher.numberOfMatches > 0) && watchingProblemMatcher.maxMarkerSeverity && + (watchingProblemMatcher.maxMarkerSeverity >= MarkerSeverity.Error)) { + let reveal = task.command.presentation!.reveal; + let revealProblems = task.command.presentation!.revealProblems; + if (revealProblems === RevealProblemKind.OnProblem) { + this.panelService.openPanel(Constants.MARKERS_PANEL_ID, true); + } else if (reveal === RevealKind.Silent) { + this.terminalService.setActiveInstance(terminal!); + this.terminalService.showPanel(false); } } } - })); - watchingProblemMatcher.aboutToStart(); - let delayer: Async.Delayer | undefined = undefined; - await terminalPromise; - if (error || !terminal) { - return; } - let processStartedSignaled = false; - terminal.processReady.then(() => { - if (!processStartedSignaled) { - if (task.command.runtime !== RuntimeType.CustomExecution) { - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); - } - processStartedSignaled = true; - } - }, (_error) => { - // The process never got ready. Need to think how to handle this. - }); - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Start, task, terminal.id)); - const registeredLinkMatchers = this.registerLinkMatchers(terminal, problemMatchers); - const onData = terminal.onLineData((line) => { - watchingProblemMatcher.processLine(line); - if (!delayer) { - delayer = new Async.Delayer(3000); + })); + watchingProblemMatcher.aboutToStart(); + let delayer: Async.Delayer | undefined = undefined; + [terminal, executedCommand, error] = await this.createTerminal(task, resolver); + + if (error) { + return Promise.reject(new Error((error).message)); + } + if (!terminal) { + return Promise.reject(new Error(`Failed to create terminal for task ${task._label}`)); + } + + let processStartedSignaled = false; + terminal.processReady.then(() => { + if (!processStartedSignaled) { + if (task.command.runtime !== RuntimeType.CustomExecution) { + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); } - delayer.trigger(() => { - watchingProblemMatcher.forceDelivery(); - delayer = undefined; - }); + processStartedSignaled = true; + } + }, (_error) => { + // The process never got ready. Need to think how to handle this. + }); + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Start, task, terminal.id)); + const registeredLinkMatchers = this.registerLinkMatchers(terminal, problemMatchers); + const onData = terminal.onLineData((line) => { + watchingProblemMatcher.processLine(line); + if (!delayer) { + delayer = new Async.Delayer(3000); + } + delayer.trigger(() => { + watchingProblemMatcher.forceDelivery(); + delayer = undefined; }); - const onExit = terminal.onExit((exitCode) => { + }); + promise = new Promise((resolve, reject) => { + const onExit = terminal!.onExit((exitCode) => { onData.dispose(); onExit.dispose(); let key = task.getMapKey(); @@ -622,36 +622,36 @@ export class TerminalTaskSystem implements ITaskSystem { }); }); } else { - terminalPromise = new Promise(async (resolveTerminal) => { - [terminal, executedCommand, error] = await this.createTerminal(task, resolver); - resolveTerminal(); - }); - promise = new Promise(async (resolve, reject) => { - await terminalPromise; - if (!terminal || error) { - return; - } + [terminal, executedCommand, error] = await this.createTerminal(task, resolver); - let processStartedSignaled = false; - terminal.processReady.then(() => { - if (!processStartedSignaled) { - if (task.command.runtime !== RuntimeType.CustomExecution) { - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); - } - processStartedSignaled = true; + if (error) { + return Promise.reject(new Error((error).message)); + } + if (!terminal) { + return Promise.reject(new Error(`Failed to create terminal for task ${task._label}`)); + } + + let processStartedSignaled = false; + terminal.processReady.then(() => { + if (!processStartedSignaled) { + if (task.command.runtime !== RuntimeType.CustomExecution) { + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.ProcessStarted, task, terminal!.processId!)); } - }, (_error) => { - // The process never got ready. Need to think how to handle this. - }); - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Start, task, terminal.id)); - this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task)); - let problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers); - let startStopProblemMatcher = new StartStopProblemCollector(problemMatchers, this.markerService, this.modelService, ProblemHandlingStrategy.Clean, this.fileService); - const registeredLinkMatchers = this.registerLinkMatchers(terminal, problemMatchers); - const onData = terminal.onLineData((line) => { - startStopProblemMatcher.processLine(line); - }); - const onExit = terminal.onExit((exitCode) => { + processStartedSignaled = true; + } + }, (_error) => { + // The process never got ready. Need to think how to handle this. + }); + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Start, task, terminal.id)); + this._onDidStateChange.fire(TaskEvent.create(TaskEventKind.Active, task)); + let problemMatchers = this.resolveMatchers(resolver, task.configurationProperties.problemMatchers); + let startStopProblemMatcher = new StartStopProblemCollector(problemMatchers, this.markerService, this.modelService, ProblemHandlingStrategy.Clean, this.fileService); + const registeredLinkMatchers = this.registerLinkMatchers(terminal, problemMatchers); + const onData = terminal.onLineData((line) => { + startStopProblemMatcher.processLine(line); + }); + promise = new Promise((resolve, reject) => { + const onExit = terminal!.onExit((exitCode) => { onData.dispose(); onExit.dispose(); let key = task.getMapKey(); @@ -698,13 +698,7 @@ export class TerminalTaskSystem implements ITaskSystem { }); }); } - await terminalPromise; - if (error) { - return Promise.reject(new Error((error).message)); - } - if (!terminal) { - return Promise.reject(new Error(`Failed to create terminal for task ${task._label}`)); - } + let showProblemPanel = task.command.presentation && (task.command.presentation.revealProblems === RevealProblemKind.Always); if (showProblemPanel) { this.panelService.openPanel(Constants.MARKERS_PANEL_ID); From 2955dbfa8efaa1cb51c00be72fb1761f0e54fbd1 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 21 Jun 2019 16:01:47 +0200 Subject: [PATCH 240/364] do not allow additionalProperties #75887 --- src/vs/workbench/contrib/debug/common/debugSchemas.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/common/debugSchemas.ts b/src/vs/workbench/contrib/debug/common/debugSchemas.ts index 9cd391a66f667..6eaa73a28385b 100644 --- a/src/vs/workbench/contrib/debug/common/debugSchemas.ts +++ b/src/vs/workbench/contrib/debug/common/debugSchemas.ts @@ -17,8 +17,9 @@ export const debuggersExtPoint = extensionsRegistry.ExtensionsRegistry.registerE jsonSchema: { description: nls.localize('vscode.extension.contributes.debuggers', 'Contributes debug adapters.'), type: 'array', - defaultSnippets: [{ body: [{ type: '', extensions: [] }] }], + defaultSnippets: [{ body: [{ type: '' }] }], items: { + additionalProperties: false, type: 'object', defaultSnippets: [{ body: { type: '', program: '', runtime: '', enableBreakpointsFor: { languageIds: [''] } } }], properties: { @@ -118,6 +119,7 @@ export const breakpointsExtPoint = extensionsRegistry.ExtensionsRegistry.registe defaultSnippets: [{ body: [{ language: '' }] }], items: { type: 'object', + additionalProperties: false, defaultSnippets: [{ body: { language: '' } }], properties: { language: { From ec3d81812cac278d0821baed6b1a476619929d29 Mon Sep 17 00:00:00 2001 From: isidor Date: Fri, 21 Jun 2019 16:45:02 +0200 Subject: [PATCH 241/364] explorer: roots forget children on new file system provider registration #75720 --- src/vs/workbench/contrib/files/common/explorerService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/files/common/explorerService.ts b/src/vs/workbench/contrib/files/common/explorerService.ts index 494351a42747e..cb6d96bd1ff3d 100644 --- a/src/vs/workbench/contrib/files/common/explorerService.ts +++ b/src/vs/workbench/contrib/files/common/explorerService.ts @@ -102,6 +102,7 @@ export class ExplorerService implements IExplorerService { this.disposables.push(this.fileService.onDidChangeFileSystemProviderRegistrations(e => { if (e.added && this.fileSystemProviderSchemes.has(e.scheme)) { // A file system provider got re-registered, we should update all file stats since they might change (got read-only) + this.model.roots.forEach(r => r.forgetChildren()); this._onDidChangeItem.fire({ recursive: true }); } else { this.fileSystemProviderSchemes.add(e.scheme); From 7583fe8aa48ae3c50a3c6f1f497506c7bcd9c010 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 21 Jun 2019 11:35:42 -0700 Subject: [PATCH 242/364] Update max tokenization limit without reload --- .../services/textMate/browser/abstractTextMateService.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts index 316a6f97a50b8..e25b10d9696f2 100644 --- a/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts +++ b/src/vs/workbench/services/textMate/browser/abstractTextMateService.ts @@ -462,6 +462,11 @@ class TMTokenization implements ITokenizationSupport { this._containsEmbeddedLanguages = containsEmbeddedLanguages; this._seenLanguages = []; this._maxTokenizationLineLength = configurationService.getValue('editor.maxTokenizationLineLength'); + configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('editor.maxTokenizationLineLength')) { + this._maxTokenizationLineLength = configurationService.getValue('editor.maxTokenizationLineLength'); + } + }); } public getInitialState(): IState { From f90a0abe02b932182bd72d689ce5dd0836583493 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 21 Jun 2019 12:03:26 -0700 Subject: [PATCH 243/364] Use interfaces for keyboard layout registration --- .../browser/keyboardLayouts/_.contribution.ts | 6 +++--- .../keybinding/browser/keyboardLayouts/cz.win.ts | 11 +++++------ .../browser/keyboardLayouts/de-swiss.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/de.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/de.linux.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/de.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/dk.win.ts | 12 ++++++------ .../browser/keyboardLayouts/en-belgian.win.ts | 12 ++++++------ .../browser/keyboardLayouts/en-ext.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/en-in.win.ts | 12 ++++++------ .../browser/keyboardLayouts/en-intl.darwin.ts | 12 ++++++------ .../browser/keyboardLayouts/en-intl.win.ts | 12 ++++++------ .../browser/keyboardLayouts/en-uk.darwin.ts | 12 +++++------- .../keybinding/browser/keyboardLayouts/en-uk.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/en.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/en.linux.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/en.win.ts | 12 ++++++------ .../browser/keyboardLayouts/es-latin.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/es.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/es.linux.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/es.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/fr.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/fr.linux.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/fr.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/hu.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/it.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/it.win.ts | 12 ++++++------ .../browser/keyboardLayouts/jp-roman.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/jp.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/ko.darwin.ts | 12 +++++------- .../keybinding/browser/keyboardLayouts/no.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/pl.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/pl.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/pt-br.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/pt.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/pt.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/ru.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/ru.linux.ts | 13 ++++++------- .../keybinding/browser/keyboardLayouts/ru.win.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/sv.darwin.ts | 12 ++++++------ .../keybinding/browser/keyboardLayouts/sv.win.ts | 13 ++++++------- .../keybinding/browser/keyboardLayouts/thai.win.ts | 11 +++++------ .../keybinding/browser/keyboardLayouts/tr.win.ts | 11 +++++------ .../browser/keyboardLayouts/zh-hans.darwin.ts | 12 +++++------- .../services/keybinding/browser/keymapService.ts | 5 +++-- .../services/keybinding/common/keymapInfo.ts | 7 +++++++ 46 files changed, 265 insertions(+), 268 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts index 846b6023774ce..89ef892047ae9 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution.ts @@ -3,12 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { IKeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; export class KeyboardLayoutContribution { public static readonly INSTANCE: KeyboardLayoutContribution = new KeyboardLayoutContribution(); - private _layoutInfos: KeymapInfo[] = []; + private _layoutInfos: IKeymapInfo[] = []; get layoutInfos() { return this._layoutInfos; @@ -17,7 +17,7 @@ export class KeyboardLayoutContribution { private constructor() { } - registerKeyboardLayout(layout: KeymapInfo) { + registerKeyboardLayout(layout: IKeymapInfo) { this._layoutInfos.push(layout); } } \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts index 8d560875c613f..c187c923cec11 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/cz.win.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000405', id: '', text: 'Czech' }, - [], - { +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000405', id: '', text: 'Czech' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -166,4 +165,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts index b7d6467220a49..b19d2935e6684 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de-swiss.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000807', id: '', text: 'Swiss German' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000807', id: '', text: 'Swiss German' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts index 6e870e8c47210..33d2f5d5e324d 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.German', lang: 'de', localizedName: 'German' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.German', lang: 'de', localizedName: 'German' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', '‹', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts index 2f7f85af3caec..b4675240ef07e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.linux.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { model: 'pc104', layout: 'de', variant: '', options: '', rules: 'base' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc104', layout: 'de', variant: '', options: '', rules: 'base' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'æ', 'Æ', 0], @@ -184,4 +184,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( MailForward: [], MailSend: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts index 0bf3c61618ecd..46bf5981a68b9 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/de.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000407', id: '', text: 'German' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000407', id: '', text: 'German' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts index 34f7f3103a73d..b774622699c93 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/dk.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000406', id: '', text: 'Danish' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000406', id: '', text: 'Danish' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -167,4 +167,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts index 6e5cae52518da..89e3a27892a72 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-belgian.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000813', id: '', text: 'Belgian (Period)' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000813', id: '', text: 'Belgian (Period)' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['q', 'Q', '', '', 0, 'VK_Q'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts index 688281af2beb7..a12a2338bff82 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-ext.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.USExtended', lang: 'en', localizedName: 'ABC - Extended' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.USExtended', lang: 'en', localizedName: 'ABC - Extended' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', '¯', '̄', 4], KeyB: ['b', 'B', '˘', '̆', 4], KeyC: ['c', 'C', '¸', '̧', 4], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts index d3ad3786dcb3b..a1786f4206192 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-in.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00004009', id: '', text: 'India' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00004009', id: '', text: 'India' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'ā', 'Ā', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts index a4f4a9e10b1a0..ceb7b67a878e6 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.USInternational-PC', lang: 'en', localizedName: 'U.S. International - PC' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.USInternational-PC', lang: 'en', localizedName: 'U.S. International - PC' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'ı', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts index ce5ade144e244..75a2a40b805b8 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-intl.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00020409', id: '0001', text: 'United States-International' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00020409', id: '0001', text: 'United States-International' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'á', 'Á', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts index 4bebc424b1fcd..89236337707fa 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.darwin.ts @@ -4,13 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - - { id: 'com.apple.keylayout.British', lang: 'en', localizedName: 'British' }, - [], - { +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.British', lang: 'en', localizedName: 'British' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'ı', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -130,4 +128,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts index d3aa6995fb91c..0b07025fa886b 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en-uk.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000809', id: '', text: 'United Kingdom' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000809', id: '', text: 'United Kingdom' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'á', 'Á', 0, 'VK_A'], @@ -167,4 +167,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts index ee78fd8254dbf..f0fca4a9d7411 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin.ts @@ -4,11 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.US', lang: 'en', localizedName: 'U.S.', isUSStandard: true }, - [ + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.US', lang: 'en', localizedName: 'U.S.', isUSStandard: true }, + secondaryLayouts: [ { id: 'com.apple.keylayout.ABC', lang: 'en', localizedName: 'ABC' }, { id: 'com.sogou.inputmethod.sogou.pinyin', lang: 'zh-Hans', localizedName: 'Pinyin - Simplified' }, { id: 'com.apple.inputmethod.Kotoeri.Roman', lang: 'en', localizedName: 'Romaji' }, @@ -17,7 +17,7 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( { id: 'com.apple.keylayout.Canadian', lang: 'en', localizedName: 'Canadian English' }, { id: 'com.apple.keylayout.Brazilian', lang: 'pt', localizedName: 'Brazilian' }, ], - { + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'ı', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -137,4 +137,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts index 1ea1d427390b1..571e9164e15a5 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.linux.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { model: 'pc105', layout: 'us', variant: '', options: '', rules: 'evdev', isUSStandard: true }, - [ + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc105', layout: 'us', variant: '', options: '', rules: 'evdev', isUSStandard: true }, + secondaryLayouts: [ { model: 'pc105', layout: 'cn', variant: '', options: '', rules: 'evdev' }, ], - { + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'a', 'A', 0], @@ -187,4 +187,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( MailSend: [] } -)); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts index be1ca6ff8b84a..3d6845dc05304 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/en.win.ts @@ -4,17 +4,17 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000409', id: '', text: 'US', isUSStandard: true }, - [ + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000409', id: '', text: 'US', isUSStandard: true }, + secondaryLayouts: [ { name: '00000804', id: '', text: 'Chinese (Simplified) - US Keyboard' }, { name: '00000411', id: '', text: 'Japanese' }, { name: '00000412', id: '', text: 'Korean' }, { name: '00000404', id: '', text: 'Chinese (Traditional) - US Keyboard' } ], - { + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -171,4 +171,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts index 6234c4542804d..16531eda2124e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es-latin.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000080A', id: '', text: 'Latin American' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000080A', id: '', text: 'Latin American' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -167,4 +167,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts index a7b3986364bc0..679dfb36d0856 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Spanish-ISO', lang: 'es', localizedName: 'Spanish - ISO' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Spanish-ISO', lang: 'es', localizedName: 'Spanish - ISO' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', 'ß', '', 0], KeyC: ['c', 'C', '©', ' ', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts index 1b4f4d9485856..8fcff46f8d6cb 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.linux.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { model: 'pc105', layout: 'es', variant: '', options: '', rules: 'evdev' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc105', layout: 'es', variant: '', options: '', rules: 'evdev' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'æ', 'Æ', 0], @@ -184,4 +184,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( MailForward: [], MailSend: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts index 8fea58dc8727f..3ac96a5dc59d7 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/es.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000040A', id: '', text: 'Spanish' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000040A', id: '', text: 'Spanish' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts index 6bc78c8a2b292..fa9198b64a0bf 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.French', lang: 'fr', localizedName: 'French' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.French', lang: 'fr', localizedName: 'French' }, + secondaryLayouts: [], + mapping: { KeyA: ['q', 'Q', '‡', 'Ω', 0], KeyB: ['b', 'B', 'ß', '∫', 0], KeyC: ['c', 'C', '©', '¢', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts index 7c857332595ce..dc9488f28c33e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.linux.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { model: 'pc104', layout: 'fr', variant: '', options: '', rules: 'base' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc104', layout: 'fr', variant: '', options: '', rules: 'base' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['q', 'Q', '@', 'Ω', 0], @@ -184,4 +184,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( MailForward: [], MailSend: [] } -)); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts index b056c38ff2dc9..c9f032d7beeb3 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/fr.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000040C', id: '', text: 'French' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000040C', id: '', text: 'French' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['q', 'Q', '', '', 0, 'VK_Q'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts index ebcce4786fdc4..d6b5a4dac0651 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/hu.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000040E', id: '', text: 'Hungarian' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000040E', id: '', text: 'Hungarian' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'ä', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts index 3d1c557e65ebb..1dc97d9903f55 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Italian-Pro', lang: 'it', localizedName: 'Italian' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Italian-Pro', lang: 'it', localizedName: 'Italian' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'Í', 0], KeyC: ['c', 'C', '©', 'Á', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts index 1b0636f02ab16..573b7b0c6c3bf 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/it.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000410', id: '', text: 'Italian' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000410', id: '', text: 'Italian' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts index 578a479dc7e83..27328f3d87b0d 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp-roman.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.google.inputmethod.Japanese.Roman', lang: 'en', localizedName: 'Alphanumeric (Google)' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.google.inputmethod.Japanese.Roman', lang: 'en', localizedName: 'Alphanumeric (Google)' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', '¯', '̄', 4], KeyB: ['b', 'B', '˘', '̆', 4], KeyC: ['c', 'C', '¸', '̧', 4], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts index 1835862116e5f..819f96ba5caaa 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/jp.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja', localizedName: 'Hiragana' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.inputmethod.Kotoeri.Japanese', lang: 'ja', localizedName: 'Hiragana' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'ı', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts index e767bd03dcd0c..4219a7bd62f8f 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ko.darwin.ts @@ -4,13 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.inputmethod.Korean.2SetKorean', lang: 'ko', localizedName: '2-Set Korean' }, - [], - { +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.inputmethod.Korean.2SetKorean', lang: 'ko', localizedName: '2-Set Korean' }, + secondaryLayouts: [], + mapping: { KeyA: ['ㅁ', 'ㅁ', 'a', 'A', 0], KeyB: ['ㅠ', 'ㅠ', 'b', 'B', 0], KeyC: ['ㅊ', 'ㅊ', 'c', 'C', 0], @@ -130,5 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } - -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts index 7183b0fbe9fca..2c415e8ebffba 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/no.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000414', id: '', text: 'Norwegian' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000414', id: '', text: 'Norwegian' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts index 8ae036710a2f0..57577ba513c79 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.PolishPro', lang: 'pl', localizedName: 'Polish - Pro' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.PolishPro', lang: 'pl', localizedName: 'Polish - Pro' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'ą', 'Ą', 0], KeyB: ['b', 'B', 'ļ', 'ű', 0], KeyC: ['c', 'C', 'ć', 'Ć', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts index 9d0576fc4f291..a110111a83fdf 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pl.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000415', id: '', text: 'Polish (Programmers)' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000415', id: '', text: 'Polish (Programmers)' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'ą', 'Ą', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts index b5886ffc968bb..9bb82448a7cbd 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt-br.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000416', id: '', text: 'Portuguese (Brazilian ABNT)' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000416', id: '', text: 'Portuguese (Brazilian ABNT)' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -167,4 +167,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts index 9a0baec47d2a7..87435fdc0eaf0 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Brazilian-Pro', lang: 'pt' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Brazilian-Pro', lang: 'pt' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'ı', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts index 2d1c72c89b965..456a537654b75 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/pt.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000816', id: '', text: 'Portuguese' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000816', id: '', text: 'Portuguese' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -167,4 +167,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts index 9140df78e5c5d..5eea5ac38f58e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Russian', lang: 'ru', localizedName: 'Russian' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Russian', lang: 'ru', localizedName: 'Russian' }, + secondaryLayouts: [], + mapping: { KeyA: ['ф', 'Ф', 'ƒ', 'ƒ', 0], KeyB: ['и', 'И', 'и', 'И', 0], KeyC: ['с', 'С', '≠', '≠', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts index c086909149a44..b13adb0d9ac34 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.linux.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { model: 'pc104', layout: 'ru', variant: ',', options: '', rules: 'base' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { model: 'pc104', layout: 'ru', variant: ',', options: '', rules: 'base' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['ф', 'Ф', 'ф', 'Ф', 0], @@ -184,5 +184,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( MailForward: [], MailSend: [] } - -)); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts index dfe753aacb070..0da492a10ac37 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/ru.win.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '00000419', id: '', text: 'Russian' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '00000419', id: '', text: 'Russian' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['ф', 'Ф', '', '', 0, 'VK_A'], @@ -166,4 +166,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts index 2c5f6f3e582b0..6d80477a6892e 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.darwin.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.keylayout.Swedish-Pro', lang: 'sv', localizedName: 'Swedish - Pro' }, - [], - { + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.keylayout.Swedish-Pro', lang: 'sv', localizedName: 'Swedish - Pro' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', '', '◊', 0], KeyB: ['b', 'B', '›', '»', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -129,4 +129,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts index 729d9a13bb083..c7128b5c929d4 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/sv.win.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000041D', id: '', text: 'Swedish' }, - [ + +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000041D', id: '', text: 'Swedish' }, + secondaryLayouts: [ { name: '0000040B', id: '', text: 'Finnish' } ], - { + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', '', '', 0, 'VK_A'], @@ -168,5 +168,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } - -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts index 013b7ac64f7dd..be85bfedd9ef8 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/thai.win.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000041E', id: '', text: 'Thai Kedmanee' }, - [], - { +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000041E', id: '', text: 'Thai Kedmanee' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['ฟ', 'ฤ', '', '', 0, 'VK_A'], @@ -166,4 +165,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); +}); diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts index 058ef5592ae51..955b03f5fc038 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/tr.win.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( - { name: '0000041F', id: '', text: 'Turkish Q' }, - [], - { +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { name: '0000041F', id: '', text: 'Turkish Q' }, + secondaryLayouts: [], + mapping: { Sleep: [], WakeUp: [], KeyA: ['a', 'A', 'æ', 'Æ', 0, 'VK_A'], @@ -166,4 +165,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout((new KeymapInfo( BrowserRefresh: [], BrowserFavorites: [] } -))); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts index df8e9252fa6f1..49d1f60ae0d0b 100644 --- a/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts +++ b/src/vs/workbench/services/keybinding/browser/keyboardLayouts/zh-hans.darwin.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; -import { KeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; -KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( - { id: 'com.apple.inputmethod.SCIM.ITABC', lang: 'zh-Hans', localizedName: '搜狗拼音' }, - [], - { +KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout({ + layout: { id: 'com.apple.inputmethod.SCIM.ITABC', lang: 'zh-Hans', localizedName: '搜狗拼音' }, + secondaryLayouts: [], + mapping: { KeyA: ['a', 'A', 'å', 'Å', 0], KeyB: ['b', 'B', '∫', 'ı', 0], KeyC: ['c', 'C', 'ç', 'Ç', 0], @@ -129,5 +128,4 @@ KeyboardLayoutContribution.INSTANCE.registerKeyboardLayout(new KeymapInfo( AltRight: [], MetaRight: [] } - -)); \ No newline at end of file +}); \ No newline at end of file diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 83c78cc166461..13434bdb7bb53 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, toDisposable, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, KeymapInfo, IRawMixedKeyboardMapping, getKeyboardLayoutId } from 'vs/workbench/services/keybinding/common/keymapInfo'; +import { IKeymapService, IKeyboardLayoutInfo, IKeyboardMapping, IWindowsKeyboardMapping, KeymapInfo, IRawMixedKeyboardMapping, getKeyboardLayoutId, IKeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { IKeyboardMapper, CachedKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; @@ -79,7 +79,8 @@ export class BrowserKeyboardMapperFactory { const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then((m) => { - this._keymapInfos.push(...m.KeyboardLayoutContribution.INSTANCE.layoutInfos); + let keymapInfos: IKeymapInfo[] = m.KeyboardLayoutContribution.INSTANCE.layoutInfos; + this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); this._mru = this._keymapInfos; this._initialized = true; this.onKeyboardLayoutChanged(); diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index c4159da4c6f8b..cc1108c5ca4a8 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -248,6 +248,13 @@ interface ISerializedMapping { [key: string]: (string | number)[]; } +export interface IKeymapInfo { + layout: IKeyboardLayoutInfo; + secondaryLayouts: IKeyboardLayoutInfo[]; + mapping: ISerializedMapping; + isUserKeyboardLayout?: boolean; +} + export class KeymapInfo { mapping: IRawMixedKeyboardMapping; isUserKeyboardLayout: boolean; From 9bc5332d797294c3e7ee14763b232bef7c156ba6 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 21 Jun 2019 13:38:40 -0700 Subject: [PATCH 244/364] Separate keyboard layout loading logic for testing --- .../keybinding/browser/keymapService.ts | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 13434bdb7bb53..21546ac6d36bb 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -28,17 +28,16 @@ import { Extensions as ConfigExtensions, IConfigurationRegistry, IConfigurationN import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard'; -export class BrowserKeyboardMapperFactory { - public static readonly INSTANCE = new BrowserKeyboardMapperFactory(); +export class BrowserKeyboardMapperFactoryBase { // keyboard mapper - private _initialized: boolean; - private _keyboardMapper: IKeyboardMapper | null; + protected _initialized: boolean; + protected _keyboardMapper: IKeyboardMapper | null; private readonly _onDidChangeKeyboardMapper = new Emitter(); public readonly onDidChangeKeyboardMapper: Event = this._onDidChangeKeyboardMapper.event; // keymap infos - private _keymapInfos: KeymapInfo[]; - private _mru: KeymapInfo[]; + protected _keymapInfos: KeymapInfo[]; + protected _mru: KeymapInfo[]; private _activeKeymapInfo: KeymapInfo | null; get activeKeymap(): KeymapInfo | null { @@ -69,23 +68,13 @@ export class BrowserKeyboardMapperFactory { return this._keymapInfos.map(keymapInfo => keymapInfo.layout); } - private constructor() { + protected constructor() { this._keyboardMapper = null; this._initialized = false; this._keymapInfos = []; this._mru = []; this._activeKeymapInfo = null; - const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; - - import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then((m) => { - let keymapInfos: IKeymapInfo[] = m.KeyboardLayoutContribution.INSTANCE.layoutInfos; - this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); - this._mru = this._keymapInfos; - this._initialized = true; - this.onKeyboardLayoutChanged(); - }); - if ((navigator).keyboard && (navigator).keyboard.addEventListener) { (navigator).keyboard.addEventListener!('layoutchange', () => { // Update user keyboard map settings @@ -371,6 +360,25 @@ export class BrowserKeyboardMapperFactory { //#endregion } +export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { + public static readonly INSTANCE = new BrowserKeyboardMapperFactory(); + // keyboard mapper + + private constructor() { + super(); + + const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux'; + + import('vs/workbench/services/keybinding/browser/keyboardLayouts/layout.contribution.' + platform).then((m) => { + let keymapInfos: IKeymapInfo[] = m.KeyboardLayoutContribution.INSTANCE.layoutInfos; + this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); + this._mru = this._keymapInfos; + this._initialized = true; + this.onKeyboardLayoutChanged(); + }); + } +} + class UserKeyboardLayout extends Disposable { private readonly reloadConfigurationScheduler: RunOnceScheduler; protected readonly _onDidChange: Emitter = this._register(new Emitter()); From 36b272f2f14eb636032546381dfff00f8cfd3136 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 21 Jun 2019 14:13:34 -0700 Subject: [PATCH 245/364] Test browser keymapper --- .../test/browserKeyboardMapper.test.ts | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts diff --git a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts new file mode 100644 index 0000000000000..a50a0e54d72d9 --- /dev/null +++ b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts @@ -0,0 +1,137 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as assert from 'assert'; +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin'; // 15% +import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin'; +import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; +import { BrowserKeyboardMapperFactoryBase } from '../browser/keymapService'; +import { KeymapInfo, IKeymapInfo } from '../common/keymapInfo'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; + +class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { + public static readonly INSTANCE = new TestKeyboardMapperFactory(); + + constructor() { + super(); + + let keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos; + this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout)))); + this._mru = this._keymapInfos; + this._initialized = true; + this.onKeyboardLayoutChanged(); + } +} + + +suite('keyboard layout loader', () => { + + test('load default US keyboard layout', () => { + assert.notEqual(TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout, null); + assert.equal(TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, true); + }); + + test('isKeyMappingActive', () => { + assert.equal(TestKeyboardMapperFactory.INSTANCE.isKeyMappingActive({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + } + }), true); + + assert.equal(TestKeyboardMapperFactory.INSTANCE.isKeyMappingActive({ + KeyA: { + value: 'a', + valueIsDeadKey: false, + withShift: 'A', + withShiftIsDeadKey: false, + withAltGr: 'å', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Å', + withShiftAltGrIsDeadKey: false + }, + KeyZ: { + value: 'z', + valueIsDeadKey: false, + withShift: 'Z', + withShiftIsDeadKey: false, + withAltGr: 'Ω', + withAltGrIsDeadKey: false, + withShiftAltGr: '¸', + withShiftAltGrIsDeadKey: false + } + }), true); + + assert.equal(TestKeyboardMapperFactory.INSTANCE.isKeyMappingActive({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + }), false); + + }); + + test('Switch keymapping', () => { + TestKeyboardMapperFactory.INSTANCE.setActiveKeyMapping({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + } + }); + assert.equal(!!TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, false); + assert.equal(TestKeyboardMapperFactory.INSTANCE.isKeyMappingActive({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + }), true); + + TestKeyboardMapperFactory.INSTANCE.setActiveKeyMapping(null); + assert.equal(TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, true); + }); + + test('Switch keyboard layout info', () => { + TestKeyboardMapperFactory.INSTANCE.setKeyboardLayout('com.apple.keylayout.German'); + assert.equal(!!TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, false); + assert.equal(TestKeyboardMapperFactory.INSTANCE.isKeyMappingActive({ + KeyZ: { + value: 'y', + valueIsDeadKey: false, + withShift: 'Y', + withShiftIsDeadKey: false, + withAltGr: '¥', + withAltGrIsDeadKey: false, + withShiftAltGr: 'Ÿ', + withShiftAltGrIsDeadKey: false + }, + }), true); + + TestKeyboardMapperFactory.INSTANCE.setActiveKeyMapping(null); + assert.equal(TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, true); + }); +}); \ No newline at end of file From 6103a134fd2f639613df9d62bbb25ba18b1c33c9 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 21 Jun 2019 14:14:10 -0700 Subject: [PATCH 246/364] unused standard keyboard event. --- .../services/keybinding/test/browserKeyboardMapper.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts index a50a0e54d72d9..6f817dc867da3 100644 --- a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts @@ -8,7 +8,6 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin'; import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution'; import { BrowserKeyboardMapperFactoryBase } from '../browser/keymapService'; import { KeymapInfo, IKeymapInfo } from '../common/keymapInfo'; -import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase { public static readonly INSTANCE = new TestKeyboardMapperFactory(); From 3490cfe9846f642380ac0a1adc9f9e4124ae01f2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 21 Jun 2019 14:43:23 -0700 Subject: [PATCH 247/364] Make sure we dismiss the zoom status bar entry when switching editors --- .../browser/parts/editor/binaryEditor.ts | 8 ++--- .../browser/parts/editor/resourceViewer.ts | 34 +++++++++++-------- .../files/browser/editors/binaryFileEditor.ts | 9 ++--- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/binaryEditor.ts b/src/vs/workbench/browser/parts/editor/binaryEditor.ts index fd12b0179c1e3..b2d51bde13c28 100644 --- a/src/vs/workbench/browser/parts/editor/binaryEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryEditor.ts @@ -20,8 +20,7 @@ import { dispose } from 'vs/base/common/lifecycle'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IFileService } from 'vs/platform/files/common/files'; -import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export interface IOpenCallbacks { openInternal: (input: EditorInput, options: EditorOptions) => Promise; @@ -53,8 +52,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor { @IFileService private readonly fileService: IFileService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IStorageService storageService: IStorageService, - @IStatusbarService private readonly statusbarService: IStatusbarService, - @IContextMenuService private readonly contextMenuService: IContextMenuService + @IInstantiationService private readonly instantiationService: IInstantiationService, ) { super(id, telemetryService, themeService, storageService); @@ -101,7 +99,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor { openInternalClb: () => this.handleOpenInternalCallback(input, options), openExternalClb: this.environmentService.configuration.remoteAuthority ? undefined : resource => this.callbacks.openExternal(resource), metadataClb: meta => this.handleMetadataChanged(meta) - }, this.statusbarService, this.contextMenuService); + }, this.instantiationService); } private async handleOpenInternalCallback(input: EditorInput, options: EditorOptions): Promise { diff --git a/src/vs/workbench/browser/parts/editor/resourceViewer.ts b/src/vs/workbench/browser/parts/editor/resourceViewer.ts index a3772c915a922..56fa7d0467612 100644 --- a/src/vs/workbench/browser/parts/editor/resourceViewer.ts +++ b/src/vs/workbench/browser/parts/editor/resourceViewer.ts @@ -19,6 +19,8 @@ import { memoize } from 'vs/base/common/decorators'; import * as platform from 'vs/base/common/platform'; import { IFileService } from 'vs/platform/files/common/files'; import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export interface IResourceDescriptor { readonly resource: URI; @@ -79,8 +81,7 @@ export class ResourceViewer { container: HTMLElement, scrollbar: DomScrollableElement, delegate: ResourceViewerDelegate, - statusbarService: IStatusbarService, - contextMenuService: IContextMenuService + instantiationService: IInstantiationService, ): ResourceViewerContext { // Ensure CSS class @@ -88,7 +89,7 @@ export class ResourceViewer { // Images if (ResourceViewer.isImageResource(descriptor)) { - return ImageView.create(container, descriptor, fileService, scrollbar, delegate, statusbarService, contextMenuService); + return ImageView.create(container, descriptor, fileService, scrollbar, delegate, instantiationService); } // Large Files @@ -120,11 +121,10 @@ class ImageView { fileService: IFileService, scrollbar: DomScrollableElement, delegate: ResourceViewerDelegate, - statusbarService: IStatusbarService, - contextMenuService: IContextMenuService + instantiationService: IInstantiationService, ): ResourceViewerContext { if (ImageView.shouldShowImageInline(descriptor)) { - return InlineImageView.create(container, descriptor, fileService, scrollbar, delegate, statusbarService, contextMenuService); + return InlineImageView.create(container, descriptor, fileService, scrollbar, delegate, instantiationService); } return LargeImageView.create(container, descriptor, delegate); @@ -237,15 +237,22 @@ type Scale = number | 'fit'; export class ZoomStatusbarItem extends Disposable { - private statusbarItem: IStatusbarEntryAccessor; + private statusbarItem?: IStatusbarEntryAccessor; onSelectScale?: (scale: Scale) => void; constructor( - private readonly contextMenuService: IContextMenuService, - private readonly statusbarService: IStatusbarService + @IEditorService editorService: IEditorService, + @IContextMenuService private readonly contextMenuService: IContextMenuService, + @IStatusbarService private readonly statusbarService: IStatusbarService, ) { super(); + this._register(editorService.onDidActiveEditorChange(() => { + if (this.statusbarItem) { + this.statusbarItem.dispose(); + this.statusbarItem = undefined; + } + })); } updateStatusbar(scale: Scale, onSelectScale?: (scale: Scale) => void): void { @@ -263,7 +270,6 @@ export class ZoomStatusbarItem extends Disposable { this._register(this.statusbarItem); const element = document.getElementById('status.imageZoom')!; - this._register(DOM.addDisposableListener(element, DOM.EventType.CLICK, (e: MouseEvent) => { this.contextMenuService.showContextMenu({ getAnchor: () => element, @@ -344,13 +350,11 @@ class InlineImageView { fileService: IFileService, scrollbar: DomScrollableElement, delegate: ResourceViewerDelegate, - statusbarService: IStatusbarService, - contextMenuService: IContextMenuService + @IInstantiationService instantiationService: IInstantiationService, ) { const disposables = new DisposableStore(); - const zoomStatusbarItem = new ZoomStatusbarItem(contextMenuService, statusbarService); - disposables.add(zoomStatusbarItem); + const zoomStatusbarItem = disposables.add(instantiationService.createInstance(ZoomStatusbarItem)); const context: ResourceViewerContext = { layout(dimension: DOM.Dimension) { }, @@ -408,8 +412,8 @@ class InlineImageView { }); InlineImageView.imageStateCache.set(cacheKey, { scale: scale, offsetX: newScrollLeft, offsetY: newScrollTop }); - } + zoomStatusbarItem.updateStatusbar(scale, updateScale); scrollbar.scanDomNode(); } diff --git a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts index 6402c9fb41429..580a2990ac4f9 100644 --- a/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/binaryFileEditor.ts @@ -16,8 +16,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { IStorageService } from 'vs/platform/storage/common/storage'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IFileService } from 'vs/platform/files/common/files'; -import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; /** * An implementation of editor for binary files like images. @@ -34,8 +33,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { @IStorageService storageService: IStorageService, @IFileService fileService: IFileService, @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, - @IStatusbarService statusbarService: IStatusbarService, - @IContextMenuService contextMenuService: IContextMenuService + @IInstantiationService instantiationService: IInstantiationService, ) { super( BinaryFileEditor.ID, @@ -48,8 +46,7 @@ export class BinaryFileEditor extends BaseBinaryResourceEditor { fileService, environmentService, storageService, - statusbarService, - contextMenuService + instantiationService, ); } From ebb0ac31651e8cc2dc1598a3597c8f361153f127 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 21 Jun 2019 14:45:16 -0700 Subject: [PATCH 248/364] Reduce state --- .../browser/parts/editor/resourceViewer.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/resourceViewer.ts b/src/vs/workbench/browser/parts/editor/resourceViewer.ts index 56fa7d0467612..a5e644112b574 100644 --- a/src/vs/workbench/browser/parts/editor/resourceViewer.ts +++ b/src/vs/workbench/browser/parts/editor/resourceViewer.ts @@ -239,9 +239,8 @@ export class ZoomStatusbarItem extends Disposable { private statusbarItem?: IStatusbarEntryAccessor; - onSelectScale?: (scale: Scale) => void; - constructor( + private readonly onSelectScale: (scale: Scale) => void, @IEditorService editorService: IEditorService, @IContextMenuService private readonly contextMenuService: IContextMenuService, @IStatusbarService private readonly statusbarService: IStatusbarService, @@ -255,15 +254,11 @@ export class ZoomStatusbarItem extends Disposable { })); } - updateStatusbar(scale: Scale, onSelectScale?: (scale: Scale) => void): void { + updateStatusbar(scale: Scale): void { const entry: IStatusbarEntry = { text: this.zoomLabel(scale) }; - if (onSelectScale) { - this.onSelectScale = onSelectScale; - } - if (!this.statusbarItem) { this.statusbarItem = this.statusbarService.addEntry(entry, 'status.imageZoom', nls.localize('status.imageZoom', "Image Zoom"), StatusbarAlignment.RIGHT, 101 /* to the left of editor status (100) */); @@ -354,7 +349,8 @@ class InlineImageView { ) { const disposables = new DisposableStore(); - const zoomStatusbarItem = disposables.add(instantiationService.createInstance(ZoomStatusbarItem)); + const zoomStatusbarItem = disposables.add(instantiationService.createInstance(ZoomStatusbarItem, + newScale => updateScale(newScale))); const context: ResourceViewerContext = { layout(dimension: DOM.Dimension) { }, @@ -414,7 +410,7 @@ class InlineImageView { InlineImageView.imageStateCache.set(cacheKey, { scale: scale, offsetX: newScrollLeft, offsetY: newScrollTop }); } - zoomStatusbarItem.updateStatusbar(scale, updateScale); + zoomStatusbarItem.updateStatusbar(scale); scrollbar.scanDomNode(); } From 402281babe08c6b1a32d7a0316fc696523db1d9d Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Fri, 21 Jun 2019 15:13:07 -0700 Subject: [PATCH 249/364] Added strictly typed telemetry function (#75915) * Added strictly typed telemetry function * cleanup publicLog2 signature --- .../standalone/browser/simpleServices.ts | 5 ++++ .../platform/telemetry/common/gdprTypings.ts | 26 +++++++++++++++++++ src/vs/platform/telemetry/common/telemetry.ts | 3 +++ .../telemetry/common/telemetryService.ts | 5 ++++ .../telemetry/common/telemetryUtils.ts | 4 +++ .../api/browser/mainThreadTelemetry.ts | 7 +++++ .../workbench/api/common/extHost.protocol.ts | 2 ++ .../workbench/browser/web.simpleservices.ts | 5 ++++ .../electron-browser/telemetryService.ts | 5 ++++ .../quickopen.perf.integrationTest.ts | 5 ++++ .../textsearch.perf.integrationTest.ts | 5 ++++ 11 files changed, 72 insertions(+) create mode 100644 src/vs/platform/telemetry/common/gdprTypings.ts diff --git a/src/vs/editor/standalone/browser/simpleServices.ts b/src/vs/editor/standalone/browser/simpleServices.ts index 7cf0082c0ddfd..1f44f24648608 100644 --- a/src/vs/editor/standalone/browser/simpleServices.ts +++ b/src/vs/editor/standalone/browser/simpleServices.ts @@ -44,6 +44,7 @@ import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFolde import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { ILayoutService, IDimension } from 'vs/platform/layout/browser/layoutService'; import { SimpleServicesNLS } from 'vs/editor/common/standaloneStrings'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export class SimpleModel implements IResolvedTextEditorModel { @@ -525,6 +526,10 @@ export class StandaloneTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as any); + } + public getTelemetryInfo(): Promise { throw new Error(`Not available`); } diff --git a/src/vs/platform/telemetry/common/gdprTypings.ts b/src/vs/platform/telemetry/common/gdprTypings.ts new file mode 100644 index 0000000000000..4fa946fb59f41 --- /dev/null +++ b/src/vs/platform/telemetry/common/gdprTypings.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +export interface IPropertyData { + classification: 'SystemMetaData' | 'CallstackOrException' | 'CustomerContent' | 'PublicNonPersonalData'; + purpose: 'PerformanceAndHealth' | 'FeatureInsight' | 'BusinessInsight'; + endpoint?: string; + isMeasurement?: boolean; +} + +export interface IGDPRProperty { + readonly [name: string]: IPropertyData | undefined | IGDPRProperty; +} + +export type ClassifiedEvent = { + [k in keyof T]: any +}; + +export type StrictPropertyChecker = keyof TEvent extends keyof TClassifiedEvent ? keyof TClassifiedEvent extends keyof TEvent ? TEvent : TError : TError; + +export type StrictPropertyCheckError = 'Type of classified event does not match event properties'; + +export type StrictPropertyCheck = StrictPropertyChecker, StrictPropertyCheckError>; + +export type GDPRClassification = { [_ in keyof T]: IPropertyData | IGDPRProperty | undefined }; \ No newline at end of file diff --git a/src/vs/platform/telemetry/common/telemetry.ts b/src/vs/platform/telemetry/common/telemetry.ts index 41924be49013d..e82693979becd 100644 --- a/src/vs/platform/telemetry/common/telemetry.ts +++ b/src/vs/platform/telemetry/common/telemetry.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export const ITelemetryService = createDecorator('telemetryService'); @@ -29,6 +30,8 @@ export interface ITelemetryService { */ publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise; + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise; + setEnabled(value: boolean): void; getTelemetryInfo(): Promise; diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index fce980fcb9a80..cab7686a85969 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -13,6 +13,7 @@ import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/co import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { cloneAndChange, mixin } from 'vs/base/common/objects'; import { Registry } from 'vs/platform/registry/common/platform'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export interface ITelemetryServiceConfig { appender: ITelemetryAppender; @@ -131,6 +132,10 @@ export class TelemetryService implements ITelemetryService { }); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean): Promise { + return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); + } + private _cleanupInfo(stack: string, anonymizeFilePaths?: boolean): string { let updatedStack = stack; diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index 69e17c36bd15e..d9e73fab37cb4 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -8,12 +8,16 @@ import { IConfigurationService, ConfigurationTarget, ConfigurationTargetToString import { IKeybindingService, KeybindingSource } from 'vs/platform/keybinding/common/keybinding'; import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { ILogService } from 'vs/platform/log/common/log'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export const NullTelemetryService = new class implements ITelemetryService { _serviceBrand: undefined; publicLog(eventName: string, data?: ITelemetryData) { return Promise.resolve(undefined); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as ITelemetryData); + } setEnabled() { } isOptedIn: true; getTelemetryInfo(): Promise { diff --git a/src/vs/workbench/api/browser/mainThreadTelemetry.ts b/src/vs/workbench/api/browser/mainThreadTelemetry.ts index 41f9947bc71b9..3b800af72846c 100644 --- a/src/vs/workbench/api/browser/mainThreadTelemetry.ts +++ b/src/vs/workbench/api/browser/mainThreadTelemetry.ts @@ -6,6 +6,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { MainThreadTelemetryShape, MainContext, IExtHostContext } from '../common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; @extHostNamedCustomer(MainContext.MainThreadTelemetry) export class MainThreadTelemetry implements MainThreadTelemetryShape { @@ -28,4 +29,10 @@ export class MainThreadTelemetry implements MainThreadTelemetryShape { data[MainThreadTelemetry._name] = true; this._telemetryService.publicLog(eventName, data); } + + $publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data: StrictPropertyCheck): void { + this.$publicLog(eventName, data as any); + } } + + diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 58ec9762b80f0..fb42af2da3628 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -46,6 +46,7 @@ import * as callHierarchy from 'vs/workbench/contrib/callHierarchy/common/callHi import { IRelativePattern } from 'vs/base/common/glob'; import { IRemoteConsoleLog } from 'vs/base/common/console'; import { VSBuffer } from 'vs/base/common/buffer'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export interface IEnvironment { isExtensionDevelopmentDebug: boolean; @@ -508,6 +509,7 @@ export interface MainThreadStorageShape extends IDisposable { export interface MainThreadTelemetryShape extends IDisposable { $publicLog(eventName: string, data?: any): void; + $publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck): void; } export interface MainThreadEditorInsetsShape extends IDisposable { diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 663f21593ea41..f5bccc1b42d04 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -51,6 +51,7 @@ import { pathsToEditors } from 'vs/workbench/common/editor'; import { IFileService } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; //#region Backup File @@ -660,6 +661,10 @@ export class SimpleTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as ITelemetryData); + } + setEnabled(value: boolean): void { } diff --git a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts index c445313f091d0..5583a243cb2c2 100644 --- a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts @@ -16,6 +16,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties'; import { TelemetryService as BaseTelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; export class TelemetryService extends Disposable implements ITelemetryService { @@ -59,6 +60,10 @@ export class TelemetryService extends Disposable implements ITelemetryService { return this.impl.publicLog(eventName, data, anonymizeFilePaths); } + publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck, anonymizeFilePaths?: boolean) { + return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); + } + getTelemetryInfo(): Promise { return this.impl.getTelemetryInfo(); } diff --git a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts index a0c7e9a27feaf..4b246719249ae 100644 --- a/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/quickopen.perf.integrationTest.ts @@ -29,6 +29,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor import { LocalSearchService } from 'vs/workbench/services/search/node/searchService'; import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; import { TestContextService, TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; namespace Timer { export interface ITimerEvent { @@ -172,6 +173,10 @@ class TestTelemetryService implements ITelemetryService { return Promise.resolve(undefined); } + public publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as any); + } + public getTelemetryInfo(): Promise { return Promise.resolve({ instanceId: 'someValue.instanceId', diff --git a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts index be16e39397aa3..e08748c6364f3 100644 --- a/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts +++ b/src/vs/workbench/test/electron-browser/textsearch.perf.integrationTest.ts @@ -33,6 +33,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { testWorkspace } from 'vs/platform/workspace/test/common/testWorkspace'; import { NullLogService, ILogService } from 'vs/platform/log/common/log'; import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration'; +import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; declare var __dirname: string; @@ -165,6 +166,10 @@ class TestTelemetryService implements ITelemetryService { return Promise.resolve(); } + public publicLog2 = never, T extends GDPRClassification = never>(eventName: string, data?: StrictPropertyCheck) { + return this.publicLog(eventName, data as any); + } + public getTelemetryInfo(): Promise { return Promise.resolve({ instanceId: 'someValue.instanceId', From d27ab54da0cfd6b275dbadd2d0d6ffe0d57e1a4e Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 21 Jun 2019 17:36:26 -0700 Subject: [PATCH 250/364] Extract port mapping helper function --- .../contrib/webview/common/portMapping.ts | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts index 3a9b8ee056af1..99c605a52f8f9 100644 --- a/src/vs/workbench/contrib/webview/common/portMapping.ts +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -9,6 +9,20 @@ import * as modes from 'vs/editor/common/modes'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; +export function extractLocalHostUriMetaDataForPortMapping(uri: URI): { address: string, port: number } | undefined { + if (uri.scheme !== 'http' && uri.scheme !== 'https') { + return undefined; + } + const localhostMatch = /^(localhost):(\d+)$/.exec(uri.authority); + if (!localhostMatch) { + return undefined; + } + return { + address: localhostMatch[1], + port: +localhostMatch[2], + }; +} + export class WebviewPortMappingManager extends Disposable { private readonly _tunnels = new Map>(); @@ -23,31 +37,25 @@ export class WebviewPortMappingManager extends Disposable { public async getRedirect(url: string): Promise { const uri = URI.parse(url); - if (uri.scheme !== 'http' && uri.scheme !== 'https') { - return undefined; - } - - const localhostMatch = /^localhost:(\d+)$/.exec(uri.authority); - if (!localhostMatch) { - return undefined; + const requestLocalHostInfo = extractLocalHostUriMetaDataForPortMapping(uri); + if (!requestLocalHostInfo) { + return requestLocalHostInfo; } - - const port = +localhostMatch[1]; for (const mapping of this.mappings()) { - if (mapping.webviewPort === port) { + if (mapping.webviewPort === requestLocalHostInfo.port) { if (this.extensionLocation && this.extensionLocation.scheme === REMOTE_HOST_SCHEME) { const tunnel = await this.getOrCreateTunnel(mapping.extensionHostPort); if (tunnel) { - return url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}(/|$)`), - `${uri.scheme}://localhost:${tunnel.tunnelLocalPort}$1`); + return uri.with({ + authority: `127.0.0.1:${tunnel.tunnelLocalPort}`, + }).toString(); } } if (mapping.webviewPort !== mapping.extensionHostPort) { - return url.replace( - new RegExp(`^${uri.scheme}://localhost:${mapping.webviewPort}(/|$)`), - `${uri.scheme}://localhost:${mapping.extensionHostPort}$1`); + return uri.with({ + authority: `${requestLocalHostInfo.address}:${mapping.extensionHostPort}` + }).toString(); } } } From 0358d08196cece5b0652cd87528b0ebc409e0d7f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 21 Jun 2019 17:39:02 -0700 Subject: [PATCH 251/364] Re-use extractLocalHostUriMetaDataForPortMapping for openUri --- .../workbench/api/browser/mainThreadWindow.ts | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadWindow.ts b/src/vs/workbench/api/browser/mainThreadWindow.ts index c9a212e48632f..533dbb62eaeb6 100644 --- a/src/vs/workbench/api/browser/mainThreadWindow.ts +++ b/src/vs/workbench/api/browser/mainThreadWindow.ts @@ -11,6 +11,7 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { ExtHostContext, ExtHostWindowShape, IExtHostContext, MainContext, MainThreadWindowShape, IOpenUriOptions } from '../common/extHost.protocol'; import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { extractLocalHostUriMetaDataForPortMapping } from 'vs/workbench/contrib/webview/common/portMapping'; @extHostNamedCustomer(MainContext.MainThreadWindow) export class MainThreadWindow implements MainThreadWindowShape { @@ -48,13 +49,11 @@ export class MainThreadWindow implements MainThreadWindowShape { async $openUri(uriComponent: UriComponents, options: IOpenUriOptions): Promise { let uri = URI.revive(uriComponent); if (options.allowTunneling && !!this.environmentService.configuration.remoteAuthority) { - if (uri.scheme === 'http' || uri.scheme === 'https') { - const port = this.getLocalhostPort(uri); - if (typeof port === 'number') { - const tunnel = await this.getOrCreateTunnel(port); - if (tunnel) { - uri = uri.with({ authority: `localhost:${tunnel.tunnelLocalPort}` }); - } + const portMappingRequest = extractLocalHostUriMetaDataForPortMapping(uri); + if (portMappingRequest) { + const tunnel = await this.getOrCreateTunnel(portMappingRequest.port); + if (tunnel) { + uri = uri.with({ authority: `127.0.0.1:${tunnel.tunnelLocalPort}` }); } } } @@ -62,14 +61,6 @@ export class MainThreadWindow implements MainThreadWindowShape { return this.windowsService.openExternal(uri.toString()); } - private getLocalhostPort(uri: URI): number | undefined { - const match = /^localhost:(\d+)$/.exec(uri.authority); - if (match) { - return +match[1]; - } - return undefined; - } - private getOrCreateTunnel(remotePort: number): Promise | undefined { const existing = this._tunnels.get(remotePort); if (existing) { From a426717b50d68810ddfbf55558d777852bc21db0 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 21 Jun 2019 17:42:48 -0700 Subject: [PATCH 252/364] Also map 127.0.0.1 in webviews and forward it for openExternal Fixes https://github.com/microsoft/vscode-remote-release/issues/108 --- src/vs/workbench/contrib/webview/common/portMapping.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts index 99c605a52f8f9..487ee92148e98 100644 --- a/src/vs/workbench/contrib/webview/common/portMapping.ts +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -13,7 +13,7 @@ export function extractLocalHostUriMetaDataForPortMapping(uri: URI): { address: if (uri.scheme !== 'http' && uri.scheme !== 'https') { return undefined; } - const localhostMatch = /^(localhost):(\d+)$/.exec(uri.authority); + const localhostMatch = /^(localhost|127\.0\.0\.1):(\d+)$/.exec(uri.authority); if (!localhostMatch) { return undefined; } From 4ebbe06e0ce0575ae7e6df7893132b84502cfbc0 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 23 Jun 2019 16:22:30 +0200 Subject: [PATCH 253/364] use empty model when content is empty --- .../workbench/services/configuration/browser/configuration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 8d4f4245f5db5..14bade5275628 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -49,7 +49,7 @@ export class UserConfiguration extends Disposable { async reload(): Promise { try { - const content = await this.userDataService.read(USER_CONFIGURATION_KEY); + const content = (await this.userDataService.read(USER_CONFIGURATION_KEY)) || '{}'; this.parser.parseContent(content); return this.parser.configurationModel; } catch (e) { From 3718e799834243b2124e51a1505bc13d796d3eb8 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sun, 23 Jun 2019 16:22:47 +0200 Subject: [PATCH 254/364] :lipstick: --- .../services/configuration/browser/configurationService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index e98c108ea0638..bf934755350ea 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -29,7 +29,7 @@ import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IFileService } from 'vs/platform/files/common/files'; -import { IUserDataService } from '../../userData/common/userDataService'; +import { IUserDataService } from 'vs/workbench/services/userData/common/userDataService'; export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { From 6a7020dd4a11e0f33b157b3df4baeec90d85701b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Sun, 23 Jun 2019 16:56:31 -0700 Subject: [PATCH 255/364] Update keyboard layout file comments --- .../contrib/preferences/browser/keyboardLayoutPicker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 35ea30c421908..ddab5c033e450 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -85,7 +85,7 @@ export class KeyboardLayoutPickerAction extends Action { private static DEFAULT_CONTENT: string = [ `// ${nls.localize('displayLanguage', 'Defines the keyboard layout used in VS Code in the browser environment.')}`, - `// ${nls.localize('doc', 'See {0} for how to generate keyboard layout information.', 'https://go.microsoft.com/fwlink/?LinkId=761051')}`, + `// ${nls.localize('doc', 'Open VS Code and run "Developer: Inspect Key Mappings (JSON)" from Command Palette.')}`, ``, `// Once you have the keyboard layout info, please paste it below.`, '\n' From 8b9005edee4c59794e1ad1bc8c73fb5b315a692e Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Sun, 23 Jun 2019 20:56:19 -0500 Subject: [PATCH 256/364] Delete breadcrumbs.filterOnType unused setting. Fixes #75969 --- .../workbench/browser/parts/editor/breadcrumbs.ts | 8 +------- .../browser/parts/editor/breadcrumbsPicker.ts | 15 +-------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index 265f7b286b405..ca8fb69dd8c1a 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -71,7 +71,6 @@ export abstract class BreadcrumbsConfig { static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); static SymbolSortOrder = BreadcrumbsConfig._stub<'position' | 'name' | 'type'>('breadcrumbs.symbolSortOrder'); - static FilterOnType = BreadcrumbsConfig._stub('breadcrumbs.filterOnType'); static FileExcludes = BreadcrumbsConfig._stub('files.exclude'); @@ -161,12 +160,7 @@ Registry.as(Extensions.Configuration).registerConfigurat localize('symbolSortOrder.name', "Show symbol outline in alphabetical order."), localize('symbolSortOrder.type', "Show symbol outline in symbol type order."), ] - }, - // 'breadcrumbs.filterOnType': { - // description: localize('filterOnType', "Controls whether the breadcrumb picker filters or highlights when typing."), - // type: 'boolean', - // default: false - // }, + } } }); diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index d2147f4c5054c..3da86172b0c4f 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -15,7 +15,7 @@ import { basename, dirname, isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/breadcrumbscontrol'; import { OutlineElement, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; -import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IConstructorSignature1, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { WorkbenchDataTree, WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService'; @@ -102,10 +102,6 @@ export abstract class BreadcrumbsPicker { this._treeContainer.style.boxShadow = `0px 5px 8px ${this._themeService.getTheme().getColor(widgetShadow)}`; this._domNode.appendChild(this._treeContainer); - - const filterConfig = BreadcrumbsConfig.FilterOnType.bindTo(this._configurationService); - this._disposables.push(filterConfig); - this._layoutInfo = { maxHeight, width, arrowSize, arrowOffset, inputHeight: 0 }; this._tree = this._createTree(this._treeContainer); @@ -129,13 +125,6 @@ export abstract class BreadcrumbsPicker { this._layout(); })); - // filter on type: state - const cfgFilterOnType = BreadcrumbsConfig.FilterOnType.bindTo(this._configurationService); - this._tree.updateOptions({ filterOnType: cfgFilterOnType.getValue() }); - this._disposables.push(this._tree.onDidUpdateOptions(e => { - this._configurationService.updateValue(cfgFilterOnType.name, e.filterOnType, ConfigurationTarget.MEMORY); - })); - this._domNode.focus(); this._setInput(input).then(() => { @@ -389,7 +378,6 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { this._disposables.push(labels); return this._instantiationService.createInstance(WorkbenchAsyncDataTree, container, new FileVirtualDelegate(), [this._instantiationService.createInstance(FileRenderer, labels)], this._instantiationService.createInstance(FileDataSource), { - filterOnType: true, multipleSelectionSupport: false, sorter: new FileSorter(), filter: this._instantiationService.createInstance(FileFilter), @@ -467,7 +455,6 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker { [new OutlineGroupRenderer(), this._instantiationService.createInstance(OutlineElementRenderer)], new OutlineDataSource(), { - filterOnType: true, expandOnlyOnTwistieClick: true, multipleSelectionSupport: false, sorter: new OutlineItemComparator(this._getOutlineItemCompareType()), From 9e02832ea8507f2dcc664c088bf78643d646e74f Mon Sep 17 00:00:00 2001 From: Chase Adams Date: Mon, 24 Jun 2019 00:57:39 -0700 Subject: [PATCH 257/364] Add quick open/input color registrations (fixes #65153) --- .../browser/parts/quickinput/quickInput.ts | 10 +++++----- .../browser/parts/quickopen/quickOpenController.ts | 4 ++-- src/vs/workbench/common/theme.ts | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 39b2c68e696e5..606817b4e51c1 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { contrastBorder, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; -import { SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND } from 'vs/workbench/common/theme'; +import { QUICK_OPEN_BACKGROUND, QUICK_OPEN_FOREGROUND } from 'vs/workbench/common/theme'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { CancellationToken } from 'vs/base/common/cancellation'; import { QuickInputList } from './quickInputList'; @@ -1512,10 +1512,10 @@ export class QuickInputService extends Component implements IQuickInputService { const titleColor = { dark: 'rgba(255, 255, 255, 0.105)', light: 'rgba(0,0,0,.06)', hc: 'black' }[theme.type]; this.titleBar.style.backgroundColor = titleColor ? titleColor.toString() : null; this.ui.inputBox.style(theme); - const sideBarBackground = theme.getColor(SIDE_BAR_BACKGROUND); - this.ui.container.style.backgroundColor = sideBarBackground ? sideBarBackground.toString() : null; - const sideBarForeground = theme.getColor(SIDE_BAR_FOREGROUND); - this.ui.container.style.color = sideBarForeground ? sideBarForeground.toString() : null; + const quickOpenBackground = theme.getColor(QUICK_OPEN_BACKGROUND); + this.ui.container.style.backgroundColor = quickOpenBackground ? quickOpenBackground.toString() : null; + const quickOpenForeground = theme.getColor(QUICK_OPEN_FOREGROUND); + this.ui.container.style.color = quickOpenForeground ? quickOpenForeground.toString() : null; const contrastBorderColor = theme.getColor(contrastBorder); this.ui.container.style.border = contrastBorderColor ? `1px solid ${contrastBorderColor}` : null; const widgetShadowColor = theme.getColor(widgetShadow); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 1c1d735ff4773..4ab01f54eed34 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -34,7 +34,7 @@ import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiat import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { SIDE_BAR_BACKGROUND, SIDE_BAR_FOREGROUND } from 'vs/workbench/common/theme'; +import { QUICK_OPEN_BACKGROUND, QUICK_OPEN_FOREGROUND } from 'vs/workbench/common/theme'; import { attachQuickOpenStyler } from 'vs/platform/theme/common/styler'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; @@ -188,7 +188,7 @@ export class QuickOpenController extends Component implements IQuickOpenService treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts) } )); - this._register(attachQuickOpenStyler(this.quickOpenWidget, this.themeService, { background: SIDE_BAR_BACKGROUND, foreground: SIDE_BAR_FOREGROUND })); + this._register(attachQuickOpenStyler(this.quickOpenWidget, this.themeService, { background: QUICK_OPEN_BACKGROUND, foreground: QUICK_OPEN_FOREGROUND })); const quickOpenContainer = this.quickOpenWidget.create(); addClass(quickOpenContainer, 'show-file-icons'); diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 8bb1a35ebf260..39ffc80047e1d 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -437,6 +437,20 @@ export const SIDE_BAR_SECTION_HEADER_BORDER = registerColor('sideBarSectionHeade }, nls.localize('sideBarSectionHeaderBorder', "Side bar section header border color. The side bar is the container for views like explorer and search.")); +// < --- Quick Input -- > + +export const QUICK_OPEN_BACKGROUND = registerColor('quickOpen.background', { + dark: SIDE_BAR_BACKGROUND, + light: SIDE_BAR_BACKGROUND, + hc: SIDE_BAR_BACKGROUND +}, nls.localize('quickOpenBackground', "Quick open background color. The quick open palette is the container for views like the command palette and file quick picker")); + +export const QUICK_OPEN_FOREGROUND = registerColor('quickOpen.foreground', { + dark: SIDE_BAR_FOREGROUND, + light: SIDE_BAR_FOREGROUND, + hc: SIDE_BAR_FOREGROUND +}, nls.localize('quickOpenForeground', "Quick open foreground color. The quick open palette is the container for views like the command palette and file quick picker")); + // < --- Title Bar --- > export const TITLE_BAR_ACTIVE_FOREGROUND = registerColor('titleBar.activeForeground', { From a559a2142d7ae8dd6a3eeafef3d945346064eebd Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Mon, 24 Jun 2019 01:33:25 -0700 Subject: [PATCH 258/364] Update API --- .../api/node/extHostExtensionService.ts | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 90e59f4f24548..9d506fc112f36 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -36,11 +36,13 @@ import { RemoteAuthorityResolverError, ExtensionExecutionContext, ExtensionKind import { IURITransformer } from 'vs/base/common/uriIpc'; interface ITestRunner { - // Old test runner spec, shipped in vscode/lib/testrunner + /** Old test runner API, as exported from `vscode/lib/testrunner` */ run(testsRoot: string, clb: (error: Error, failures?: number) => void): void; +} - // New test runner spec - runTests(): Promise; +interface INewTestRunner { + /** New test runner API, as explained in the extension test doc */ + run(): Promise; } export interface IHostUtils { @@ -530,7 +532,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { const extensionTestsPath = originalFSPath(extensionTestsLocationURI); // Require the test runner via node require from the provided path - let testRunner: ITestRunner | undefined; + let testRunner: ITestRunner | INewTestRunner | undefined; let requireError: Error | undefined; try { testRunner = require.__$__nodeRequire(extensionTestsPath); @@ -538,29 +540,10 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { requireError = error; } - // Execute the runner following the new `runTests` spec - if (testRunner && typeof testRunner.runTests === 'function') { - return new Promise((c, e) => { - testRunner!.runTests() - .then((succeeded) => { - if (succeeded) { - c(undefined); - this._gracefulExit(0); - } else { - this._gracefulExit(1); - } - }) - .catch(err => { - e(err); - this._gracefulExit(1); - }); - }); - } - // Execute the runner if it follows the old `run` spec if (testRunner && typeof testRunner.run === 'function') { return new Promise((c, e) => { - testRunner!.run(extensionTestsPath, (error, failures) => { + const oldTestRunnerCallback = (error: Error, failures: number | undefined) => { if (error) { e(error.toString()); } else { @@ -569,7 +552,22 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { // after tests have run, we shutdown the host this._gracefulExit(error || (typeof failures === 'number' && failures > 0) ? 1 /* ERROR */ : 0 /* OK */); - }); + }; + + const runResult = testRunner!.run(extensionTestsPath, oldTestRunnerCallback); + + // Using the new API `run(): Promise` + if (runResult && runResult.then) { + runResult + .then(() => { + c(); + this._gracefulExit(0); + }) + .catch((err) => { + e(err); + this._gracefulExit(1); + }); + } }); } From 422fd46b942e5eabba2f4fa1867d076e4b58fb8c Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 10:35:55 +0200 Subject: [PATCH 259/364] implements ExtHostEditorInsetsShape --- src/vs/workbench/api/common/extHostCodeInsets.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/common/extHostCodeInsets.ts b/src/vs/workbench/api/common/extHostCodeInsets.ts index 398afff564f61..5a6773d443893 100644 --- a/src/vs/workbench/api/common/extHostCodeInsets.ts +++ b/src/vs/workbench/api/common/extHostCodeInsets.ts @@ -5,13 +5,13 @@ import { Emitter } from 'vs/base/common/event'; import * as vscode from 'vscode'; -import { MainThreadEditorInsetsShape } from './extHost.protocol'; +import { MainThreadEditorInsetsShape, ExtHostEditorInsetsShape } from './extHost.protocol'; import { ExtHostEditors } from 'vs/workbench/api/common/extHostTextEditors'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ExtHostTextEditor } from 'vs/workbench/api/common/extHostTextEditor'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; -export class ExtHostEditorInsets implements ExtHostEditorInsets { +export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { private _handlePool = 0; private _disposables = new DisposableStore(); From 8d1de35a463b9d1b235e2c4a12bf331ef5cf3c3c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 24 Jun 2019 10:40:24 +0200 Subject: [PATCH 260/364] use divs for tree indent guides fixes #75779 --- src/vs/base/browser/ui/tree/abstractTree.ts | 52 +++++++-------------- src/vs/base/browser/ui/tree/media/tree.css | 24 +++++----- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index c3527a710b8d0..dad7d26545a39 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -243,7 +243,7 @@ class TreeRenderer implements IListRenderer, SVGLineElement>(); + private renderedIndentGuides = new SetMap, HTMLDivElement>(); private activeParentNodes = new Set>(); private indentGuidesDisposable: IDisposable = Disposable.None; @@ -312,7 +312,7 @@ class TreeRenderer implements IListRenderer implements IListRenderer, templateData: ITreeListTemplateData) { @@ -371,51 +371,35 @@ class TreeRenderer implements IListRenderer, templateData: ITreeListTemplateData, height: number): void { + private renderIndentGuides(target: ITreeNode, templateData: ITreeListTemplateData): void { + clearNode(templateData.indent); + templateData.indentGuidesDisposable.dispose(); + if (this._renderIndentGuides === RenderIndentGuides.None) { - clearNode(templateData.indent); return; } - templateData.indentGuidesDisposable.dispose(); - const disposableStore = new DisposableStore(); - const width = this.indent * target.depth; - const virtualWidth = width * window.devicePixelRatio; - const virtualHeight = height * window.devicePixelRatio; - - const svg = $.SVG('svg', { - preserveAspectRatio: 'none', - width: `${width}`, - height: `${height}`, - viewBox: `0 0 ${virtualWidth} ${virtualHeight}` - }); - let node = target; - let i = 1; while (node.parent && node.parent.parent) { const parent = node.parent; - const x = Math.floor((target.depth - i - 1) * this.indent * window.devicePixelRatio) + 2.5; - const line = $.SVG('line', { x1: x, y1: 0, x2: x, y2: virtualHeight }); + const guide = $('.indent-guide', { style: `width: ${this.indent}px` }); if (this.activeParentNodes.has(parent)) { - addClass(line, 'active'); + addClass(guide, 'active'); } - svg.appendChild(line); + if (templateData.indent.childElementCount === 0) { + templateData.indent.appendChild(guide); + } else { + templateData.indent.insertBefore(guide, templateData.indent.firstElementChild); + } - this.renderedIndentGuides.add(parent, line); - disposableStore.add(toDisposable(() => this.renderedIndentGuides.delete(parent, line))); + this.renderedIndentGuides.add(parent, guide); + disposableStore.add(toDisposable(() => this.renderedIndentGuides.delete(parent, guide))); node = parent; - i++; - } - - clearNode(templateData.indent); - - if (svg.firstChild) { - templateData.indent.appendChild(svg); } templateData.indentGuidesDisposable = disposableStore; @@ -1358,8 +1342,8 @@ export abstract class AbstractTree implements IDisposable const content: string[] = []; if (styles.treeIndentGuidesStroke) { - content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > svg > line, .monaco-list${suffix}.always .monaco-tl-indent > svg > line { stroke: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`); - content.push(`.monaco-list${suffix} .monaco-tl-indent > svg > line.active { stroke: ${styles.treeIndentGuidesStroke}; }`); + content.push(`.monaco-list${suffix}:hover .monaco-tl-indent > .indent-guide, .monaco-list${suffix}.always .monaco-tl-indent > .indent-guide { border-color: ${styles.treeIndentGuidesStroke.transparent(0.4)}; }`); + content.push(`.monaco-list${suffix} .monaco-tl-indent > .indent-guide.active { border-color: ${styles.treeIndentGuidesStroke}; }`); } const newStyles = content.join('\n'); diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 262b33ded2248..0ba2eb422e03b 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -14,16 +14,23 @@ height: 100%; position: absolute; top: 0; - left: 14px; + left: 18px; pointer-events: none; } .hide-arrows .monaco-tl-indent { - left: 10px; + left: 12px; } -.monaco-tl-indent > svg { - overflow: visible; +.monaco-tl-indent > .indent-guide { + display: inline-block; + box-sizing: border-box; + height: 100%; + border-left: 1px solid transparent; +} + +.monaco-tl-indent > .indent-guide { + transition: border-color 0.1s linear; } .monaco-tl-twistie, @@ -84,12 +91,3 @@ .hc-black .monaco-tl-twistie.loading { background-image: url("loading-hc.svg"); } - -.monaco-list .monaco-tl-indent > svg { - height: 100%; -} - -.monaco-list .monaco-tl-indent > svg > line { - stroke: transparent; - transition: stroke 0.1s linear; -} \ No newline at end of file From d813315714aad6390f59cc6a10458d19267d4001 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 10:49:34 +0200 Subject: [PATCH 261/364] comment out more (for #74898) --- .../src/singlefolder-tests/workspace.test.ts | 12 ++++++------ scripts/test-integration.bat | 10 +++++----- scripts/test-integration.sh | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index 67059e58c5069..dc700abdf1b89 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -513,28 +513,28 @@ suite('workspace-namespace', () => { }); }); - (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles', () => { + test('findFiles', () => { return vscode.workspace.findFiles('**/*.png').then((res) => { assert.equal(res.length, 2); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); }); - (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles - exclude', () => { + test('findFiles - exclude', () => { return vscode.workspace.findFiles('**/*.png').then((res) => { assert.equal(res.length, 2); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); }); - (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles, exclude', () => { + test('findFiles, exclude', () => { return vscode.workspace.findFiles('**/*.png', '**/sub/**').then((res) => { assert.equal(res.length, 1); assert.equal(basename(vscode.workspace.asRelativePath(res[0])), 'image.png'); }); }); - (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findFiles, cancellation', () => { + test('findFiles, cancellation', () => { const source = new vscode.CancellationTokenSource(); const token = source.token; // just to get an instance first @@ -545,7 +545,7 @@ suite('workspace-namespace', () => { }); }); - (process.platform === 'win32' ? test.skip /* https://github.com/microsoft/vscode/issues/74898 */ : test)('findTextInFiles', async () => { + test('findTextInFiles', async () => { const options: vscode.FindTextInFilesOptions = { include: '*.ts', previewOptions: { @@ -565,7 +565,7 @@ suite('workspace-namespace', () => { assert.equal(vscode.workspace.asRelativePath(match.uri), '10linefile.ts'); }); - (process.platform === 'win32' ? suite.skip /* https://github.com/microsoft/vscode/issues/74898 */ : suite)('findTextInFiles, cancellation', async () => { + test('findTextInFiles, cancellation', async () => { const results: vscode.TextSearchResult[] = []; const cancellation = new vscode.CancellationTokenSource(); cancellation.cancel(); diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index cf8902a2bce0d..4f38bc04c5ad5 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -23,12 +23,12 @@ call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDeve if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in commonJS (HTML, CSS, JSON language server tests...) -call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\*\server\out\test\**\*.test.js -if %errorlevel% neq 0 exit /b %errorlevel% +REM call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\*\server\out\test\**\*.test.js +REM if %errorlevel% neq 0 exit /b %errorlevel% -if exist ".\resources\server\test\test-remote-integration.bat" ( - call .\resources\server\test\test-remote-integration.bat -) +REM if exist ".\resources\server\test\test-remote-integration.bat" ( +REM call .\resources\server\test\test-remote-integration.bat +REM ) rmdir /s /q %VSCODEUSERDATADIR% diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index a9058442dce28..3d397ed204ee7 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -21,9 +21,9 @@ cd $ROOT ./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started ./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -# mkdir -p $ROOT/extensions/emmet/test-fixtures -# ./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -# rm -rf $ROOT/extensions/emmet/test-fixtures +mkdir -p $ROOT/extensions/emmet/test-fixtures +./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +rm -rf $ROOT/extensions/emmet/test-fixtures if [ -f ./resources/server/test/test-remote-integration.sh ]; then ./resources/server/test/test-remote-integration.sh From cc6b5c3487df7581cf4b9f198fbcdf3052057a5b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 24 Jun 2019 11:26:19 +0200 Subject: [PATCH 262/364] Quick Open > Quick Input (#65153) --- .../workbench/browser/parts/quickinput/quickInput.ts | 10 +++++----- .../browser/parts/quickopen/quickOpenController.ts | 4 ++-- src/vs/workbench/common/theme.ts | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 606817b4e51c1..b2e36ae2e74d7 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { contrastBorder, widgetShadow } from 'vs/platform/theme/common/colorRegistry'; -import { QUICK_OPEN_BACKGROUND, QUICK_OPEN_FOREGROUND } from 'vs/workbench/common/theme'; +import { QUICK_INPUT_BACKGROUND, QUICK_INPUT_FOREGROUND } from 'vs/workbench/common/theme'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { CancellationToken } from 'vs/base/common/cancellation'; import { QuickInputList } from './quickInputList'; @@ -1512,10 +1512,10 @@ export class QuickInputService extends Component implements IQuickInputService { const titleColor = { dark: 'rgba(255, 255, 255, 0.105)', light: 'rgba(0,0,0,.06)', hc: 'black' }[theme.type]; this.titleBar.style.backgroundColor = titleColor ? titleColor.toString() : null; this.ui.inputBox.style(theme); - const quickOpenBackground = theme.getColor(QUICK_OPEN_BACKGROUND); - this.ui.container.style.backgroundColor = quickOpenBackground ? quickOpenBackground.toString() : null; - const quickOpenForeground = theme.getColor(QUICK_OPEN_FOREGROUND); - this.ui.container.style.color = quickOpenForeground ? quickOpenForeground.toString() : null; + const quickInputBackground = theme.getColor(QUICK_INPUT_BACKGROUND); + this.ui.container.style.backgroundColor = quickInputBackground ? quickInputBackground.toString() : null; + const quickInputForeground = theme.getColor(QUICK_INPUT_FOREGROUND); + this.ui.container.style.color = quickInputForeground ? quickInputForeground.toString() : null; const contrastBorderColor = theme.getColor(contrastBorder); this.ui.container.style.border = contrastBorderColor ? `1px solid ${contrastBorderColor}` : null; const widgetShadowColor = theme.getColor(widgetShadow); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 4ab01f54eed34..5851bdb62cee0 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -34,7 +34,7 @@ import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiat import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { QUICK_OPEN_BACKGROUND, QUICK_OPEN_FOREGROUND } from 'vs/workbench/common/theme'; +import { QUICK_INPUT_BACKGROUND, QUICK_INPUT_FOREGROUND } from 'vs/workbench/common/theme'; import { attachQuickOpenStyler } from 'vs/platform/theme/common/styler'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IFileService } from 'vs/platform/files/common/files'; @@ -188,7 +188,7 @@ export class QuickOpenController extends Component implements IQuickOpenService treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts) } )); - this._register(attachQuickOpenStyler(this.quickOpenWidget, this.themeService, { background: QUICK_OPEN_BACKGROUND, foreground: QUICK_OPEN_FOREGROUND })); + this._register(attachQuickOpenStyler(this.quickOpenWidget, this.themeService, { background: QUICK_INPUT_BACKGROUND, foreground: QUICK_INPUT_FOREGROUND })); const quickOpenContainer = this.quickOpenWidget.create(); addClass(quickOpenContainer, 'show-file-icons'); diff --git a/src/vs/workbench/common/theme.ts b/src/vs/workbench/common/theme.ts index 39ffc80047e1d..2d453924e8ad3 100644 --- a/src/vs/workbench/common/theme.ts +++ b/src/vs/workbench/common/theme.ts @@ -439,17 +439,17 @@ export const SIDE_BAR_SECTION_HEADER_BORDER = registerColor('sideBarSectionHeade // < --- Quick Input -- > -export const QUICK_OPEN_BACKGROUND = registerColor('quickOpen.background', { +export const QUICK_INPUT_BACKGROUND = registerColor('quickInput.background', { dark: SIDE_BAR_BACKGROUND, light: SIDE_BAR_BACKGROUND, hc: SIDE_BAR_BACKGROUND -}, nls.localize('quickOpenBackground', "Quick open background color. The quick open palette is the container for views like the command palette and file quick picker")); +}, nls.localize('quickInputBackground', "Quick Input background color. The Quick Input widget is the container for views like the color theme picker")); -export const QUICK_OPEN_FOREGROUND = registerColor('quickOpen.foreground', { +export const QUICK_INPUT_FOREGROUND = registerColor('quickInput.foreground', { dark: SIDE_BAR_FOREGROUND, light: SIDE_BAR_FOREGROUND, hc: SIDE_BAR_FOREGROUND -}, nls.localize('quickOpenForeground', "Quick open foreground color. The quick open palette is the container for views like the command palette and file quick picker")); +}, nls.localize('quickInputForeground', "Quick Input foreground color. The Quick Input widget is the container for views like the color theme picker")); // < --- Title Bar --- > From 0b62cdf464062a119a39656a07b63418e916d52d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 12:11:26 +0200 Subject: [PATCH 263/364] build - enable language server tests again (for #74898) --- scripts/test-integration.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index 4f38bc04c5ad5..1c189ec7b1b3c 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -23,8 +23,8 @@ call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDeve if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in commonJS (HTML, CSS, JSON language server tests...) -REM call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\*\server\out\test\**\*.test.js -REM if %errorlevel% neq 0 exit /b %errorlevel% +call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\*\server\out\test\**\*.test.js +if %errorlevel% neq 0 exit /b %errorlevel% REM if exist ".\resources\server\test\test-remote-integration.bat" ( REM call .\resources\server\test\test-remote-integration.bat From c9e7a0ba11c314a46962a98b60b591ff62e1e73c Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 24 Jun 2019 12:17:56 +0200 Subject: [PATCH 264/364] use polish for wsl1 --- .../files/node/diskFileSystemProvider.ts | 42 +++++++++++++------ .../watcher/unix/chokidarWatcherService.ts | 13 +++--- .../files/node/watcher/unix/watcher.ts | 2 + .../files/node/watcher/unix/watcherService.ts | 8 ++-- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/vs/workbench/services/files/node/diskFileSystemProvider.ts b/src/vs/workbench/services/files/node/diskFileSystemProvider.ts index 530f3ea5c235d..a645ac84ef03c 100644 --- a/src/vs/workbench/services/files/node/diskFileSystemProvider.ts +++ b/src/vs/workbench/services/files/node/diskFileSystemProvider.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { mkdir, open, close, read, write, fdatasync } from 'fs'; +import * as os from 'os'; import { promisify } from 'util'; import { IDisposable, Disposable, toDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle'; import { IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError } from 'vs/platform/files/common/files'; @@ -408,22 +409,30 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro folders: { path: string, excludes: string[] }[], onChange: (changes: IDiskFileChange[]) => void, onLogMessage: (msg: ILogMessage) => void, - verboseLogging: boolean + verboseLogging: boolean, + watcherOptions?: { [key: string]: boolean | number | string } ): WindowsWatcherService | UnixWatcherService | NsfwWatcherService }; - - // Single Folder Watcher - if (this.recursiveFoldersToWatch.length === 1) { - if (isWindows) { - watcherImpl = WindowsWatcherService; - } else { - watcherImpl = UnixWatcherService; + let watcherOptions = undefined; + + if (this.forcePolling()) { + // WSL needs a polling watcher + watcherImpl = UnixWatcherService; + watcherOptions = { usePolling: true }; + } else { + // Single Folder Watcher + if (this.recursiveFoldersToWatch.length === 1) { + if (isWindows) { + watcherImpl = WindowsWatcherService; + } else { + watcherImpl = UnixWatcherService; + } } - } - // Multi Folder Watcher - else { - watcherImpl = NsfwWatcherService; + // Multi Folder Watcher + else { + watcherImpl = NsfwWatcherService; + } } // Create and start watching @@ -436,7 +445,8 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro } this.logService[msg.type](msg.message); }, - this.logService.getLevel() === LogLevel.Trace + this.logService.getLevel() === LogLevel.Trace, + watcherOptions ); if (!this.recursiveWatcherLogLevelListener) { @@ -504,6 +514,12 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro return createFileSystemProviderError(error, code); } + + forcePolling(): boolean { + // wsl1 needs polling + return isLinux && /^[\.\-0-9]+-Microsoft/.test(os.release()); + } + //#endregion dispose(): void { diff --git a/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts b/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts index db31180b5a1b9..a95c7e4263242 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts @@ -14,7 +14,7 @@ import { ThrottledDelayer } from 'vs/base/common/async'; import { normalizeNFC } from 'vs/base/common/normalization'; import { realcaseSync } from 'vs/base/node/extpath'; import { isMacintosh, isLinux } from 'vs/base/common/platform'; -import { IDiskFileChange, normalizeFileChanges, ILogMessage } from 'vs/workbench/services/files/node/watcher/watcher'; +import { IDiskFileChange, normalizeFileChanges, ILogMessage, isWSL1 } from 'vs/workbench/services/files/node/watcher/watcher'; import { IWatcherRequest, IWatcherService, IWatcherOptions } from 'vs/workbench/services/files/node/watcher/unix/watcher'; import { Emitter, Event } from 'vs/base/common/event'; @@ -23,10 +23,6 @@ interface IWatcher { stop(): any; } -export interface IChockidarWatcherOptions { - pollingInterval?: number; -} - interface ExtendedWatcherRequest extends IWatcherRequest { parsedPattern?: glob.ParsedPattern; } @@ -52,7 +48,7 @@ export class ChokidarWatcherService implements IWatcherService { private _onLogMessage = new Emitter(); readonly onLogMessage: Event = this._onLogMessage.event; - public watch(options: IWatcherOptions & IChockidarWatcherOptions): Event { + public watch(options: IWatcherOptions): Event { this._pollingInterval = options.pollingInterval; this._watchers = Object.create(null); this._watcherCount = 0; @@ -106,6 +102,10 @@ export class ChokidarWatcherService implements IWatcherService { } const pollingInterval = this._pollingInterval || 1000; + const usePolling = isWSL1(); + if (usePolling && this._verboseLogging) { + this.log(`Use polling instead of fs.watch.`); + } const watcherOpts: chokidar.IOptions = { ignoreInitial: true, @@ -113,6 +113,7 @@ export class ChokidarWatcherService implements IWatcherService { followSymlinks: true, // this is the default of chokidar and supports file events through symlinks interval: pollingInterval, // while not used in normal cases, if any error causes chokidar to fallback to polling, increase its intervals binaryInterval: pollingInterval, + usePolling: usePolling, disableGlobbing: true // fix https://github.com/Microsoft/vscode/issues/4586 }; diff --git a/src/vs/workbench/services/files/node/watcher/unix/watcher.ts b/src/vs/workbench/services/files/node/watcher/unix/watcher.ts index fa5d4b23335b0..fc87e15803a33 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcher.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcher.ts @@ -12,6 +12,8 @@ export interface IWatcherRequest { } export interface IWatcherOptions { + pollingInterval?: number; + usePolling?: boolean; } export interface IWatcherService { diff --git a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts index 887932e9e714f..202b505d53a54 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/watcherService.ts @@ -8,7 +8,7 @@ import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { IDiskFileChange, ILogMessage } from 'vs/workbench/services/files/node/watcher/watcher'; import { WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/unix/watcherIpc'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IWatcherRequest } from 'vs/workbench/services/files/node/watcher/unix/watcher'; +import { IWatcherRequest, IWatcherOptions } from 'vs/workbench/services/files/node/watcher/unix/watcher'; import { getPathFromAmdModule } from 'vs/base/common/amd'; export class FileWatcher extends Disposable { @@ -22,7 +22,8 @@ export class FileWatcher extends Disposable { private folders: IWatcherRequest[], private onFileChanges: (changes: IDiskFileChange[]) => void, private onLogMessage: (msg: ILogMessage) => void, - private verboseLogging: boolean + private verboseLogging: boolean, + private watcherOptions: IWatcherOptions = {} ) { super(); @@ -66,8 +67,7 @@ export class FileWatcher extends Disposable { this.service.setVerboseLogging(this.verboseLogging); - const options = {}; - this._register(this.service.watch(options)(e => !this.isDisposed && this.onFileChanges(e))); + this._register(this.service.watch(this.watcherOptions)(e => !this.isDisposed && this.onFileChanges(e))); this._register(this.service.onLogMessage(m => this.onLogMessage(m))); From 0c22cee46b93da9bca49166b73e6e0daa3264307 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 12:31:12 +0200 Subject: [PATCH 265/364] move extension kind to Extension-interface --- src/vs/vscode.proposed.d.ts | 2 +- .../api/common/extHostExtensionActivator.ts | 2 -- src/vs/workbench/api/node/extHost.api.impl.ts | 18 ++++++++++++------ .../api/node/extHostExtensionService.ts | 3 +-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0ac46132de54e..1ddff5bff6d5f 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -46,7 +46,7 @@ declare module 'vscode' { Workspace = 2 } - export interface ExtensionContext { + export interface Extension { /** * The extension kind describes if an extension runs where the UI runs diff --git a/src/vs/workbench/api/common/extHostExtensionActivator.ts b/src/vs/workbench/api/common/extHostExtensionActivator.ts index b38a447ab685f..8ba9dbd8162c9 100644 --- a/src/vs/workbench/api/common/extHostExtensionActivator.ts +++ b/src/vs/workbench/api/common/extHostExtensionActivator.ts @@ -8,7 +8,6 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ExtensionActivationError, MissingDependencyError } from 'vs/workbench/services/extensions/common/extensions'; -import { ExtensionKind } from 'vs/workbench/api/common/extHostTypes'; const NO_OP_VOID_PROMISE = Promise.resolve(undefined); @@ -28,7 +27,6 @@ export interface IExtensionContext { asAbsolutePath(relativePath: string): string; readonly logPath: string; executionContext: number; - extensionKind: ExtensionKind; } /** diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index f970b136e8041..9bb9a6a92a437 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -284,17 +284,21 @@ export function createApiFactory( Object.freeze(env); } + const extensionKind = initData.remote.isRemote + ? extHostTypes.ExtensionKind.Workspace + : extHostTypes.ExtensionKind.UI; + // namespace: extensions const extensions: typeof vscode.extensions = { getExtension(extensionId: string): Extension | undefined { const desc = extensionRegistry.getExtensionDescription(extensionId); if (desc) { - return new Extension(extensionService, desc); + return new Extension(extensionService, desc, extensionKind); } return undefined; }, get all(): Extension[] { - return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc)); + return extensionRegistry.getAllExtensionDescriptions().map((desc) => new Extension(extensionService, desc, extensionKind)); }, get onDidChange() { return extensionRegistry.onDidChange; @@ -906,16 +910,18 @@ class Extension implements vscode.Extension { private _extensionService: ExtHostExtensionService; private _identifier: ExtensionIdentifier; - public id: string; - public extensionPath: string; - public packageJSON: IExtensionDescription; + readonly id: string; + readonly extensionPath: string; + readonly packageJSON: IExtensionDescription; + readonly extensionKind: vscode.ExtensionKind; - constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription) { + constructor(extensionService: ExtHostExtensionService, description: IExtensionDescription, kind: extHostTypes.ExtensionKind) { this._extensionService = extensionService; this._identifier = description.identifier; this.id = description.identifier.value; this.extensionPath = path.normalize(originalFSPath(description.extensionLocation)); this.packageJSON = description; + this.extensionKind = kind; } get isActive(): boolean { diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 69d976b10d014..cff54445d0e7f 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -32,7 +32,7 @@ import { withNullAsUndefined } from 'vs/base/common/types'; import { VSBuffer } from 'vs/base/common/buffer'; import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento'; import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; -import { RemoteAuthorityResolverError, ExtensionExecutionContext, ExtensionKind } from 'vs/workbench/api/common/extHostTypes'; +import { RemoteAuthorityResolverError, ExtensionExecutionContext } from 'vs/workbench/api/common/extHostTypes'; import { IURITransformer } from 'vs/base/common/uriIpc'; interface ITestRunner { @@ -362,7 +362,6 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { asAbsolutePath: (relativePath: string) => { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); }, logPath: that._extHostLogService.getLogDirectory(extensionDescription.identifier), executionContext: this._initData.remote.isRemote ? ExtensionExecutionContext.Remote : ExtensionExecutionContext.Local, - extensionKind: this._initData.remote.isRemote ? ExtensionKind.Workspace : ExtensionKind.UI }); }); } From c8379e2bd0993fd035b8262f6623afeb0c54001b Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 24 Jun 2019 14:28:42 +0200 Subject: [PATCH 266/364] init log level of remote log service --- package.json | 2 +- .../contrib/remote/common/remote.contribution.ts | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8ea694500f24b..c8047f1c9e6a1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "8bfb613ef059967ffe5a69e3b151c29885c8c108", + "distro": "e2de7806e752fbcf8be2bf6d3b0476cc49937ff0", "author": { "name": "Microsoft Corporation" }, diff --git a/src/vs/workbench/contrib/remote/common/remote.contribution.ts b/src/vs/workbench/contrib/remote/common/remote.contribution.ts index f169fda95d143..9235c739fb014 100644 --- a/src/vs/workbench/contrib/remote/common/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/common/remote.contribution.ts @@ -12,10 +12,11 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { Schemas } from 'vs/base/common/network'; import { IRemoteAgentService, RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService'; import { ILogService } from 'vs/platform/log/common/log'; -import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc'; +import { LogLevelSetterChannelClient } from 'vs/platform/log/common/logIpc'; import { IOutputChannelRegistry, Extensions as OutputExt, } from 'vs/workbench/contrib/output/common/output'; import { localize } from 'vs/nls'; import { joinPath } from 'vs/base/common/resources'; +import { Disposable } from 'vs/base/common/lifecycle'; export class LabelContribution implements IWorkbenchContribution { constructor( @@ -44,15 +45,18 @@ export class LabelContribution implements IWorkbenchContribution { } } -class RemoteChannelsContribution implements IWorkbenchContribution { +class RemoteChannelsContribution extends Disposable implements IWorkbenchContribution { constructor( @ILogService logService: ILogService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, ) { + super(); const connection = remoteAgentService.getConnection(); if (connection) { - connection.registerChannel('loglevel', new LogLevelSetterChannel(logService)); + const logLevelClient = new LogLevelSetterChannelClient(connection.getChannel('loglevel')); + logLevelClient.setLevel(logService.getLevel()); + this._register(logService.onDidChangeLogLevel(level => logLevelClient.setLevel(level))); } } } From 923e3d38b6b562521c85a6a8a542c13eb19aeb0d Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 24 Jun 2019 14:29:20 +0200 Subject: [PATCH 267/364] Open/Save local commands should not show in the command palette Fixes #75737 --- .../browser/actions/workspaceActions.ts | 102 +++++++----------- .../files/browser/fileActions.contribution.ts | 40 ++++++- .../electron-browser/main.contribution.ts | 5 +- .../dialogs/browser/remoteFileDialog.ts | 6 +- 4 files changed, 81 insertions(+), 72 deletions(-) diff --git a/src/vs/workbench/browser/actions/workspaceActions.ts b/src/vs/workbench/browser/actions/workspaceActions.ts index 68fe0859f5916..3cd1005e09d73 100644 --- a/src/vs/workbench/browser/actions/workspaceActions.ts +++ b/src/vs/workbench/browser/actions/workspaceActions.ts @@ -11,7 +11,7 @@ import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/p import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing'; import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands'; import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -39,44 +39,33 @@ export class OpenFileAction extends Action { } } -export class OpenLocalFileAction extends Action { +export namespace OpenLocalFileCommand { + export const ID = 'workbench.action.files.openLocalFile'; + export const LABEL = nls.localize('openLocalFile', "Open Local File..."); - static readonly ID = 'workbench.action.files.openLocalFile'; - static LABEL = nls.localize('openLocalFile', "Open Local File..."); - - constructor( - id: string, - label: string, - @IFileDialogService private readonly dialogService: IFileDialogService - ) { - super(id, label); - } - - run(event?: any, data?: ITelemetryData): Promise { - return this.dialogService.pickFileAndOpen({ forceNewWindow: false, telemetryExtraData: data, availableFileSystems: [Schemas.file] }); + export function handler(): ICommandHandler { + return accessor => { + const dialogService = accessor.get(IFileDialogService); + return dialogService.pickFileAndOpen({ forceNewWindow: false, availableFileSystems: [Schemas.file] }); + }; } } -export class SaveLocalFileAction extends Action { - - static readonly ID = 'workbench.action.files.saveLocalFile'; - static LABEL = nls.localize('saveLocalFile', "Save Local File..."); - - constructor( - id: string, - label: string, - @ITextFileService private readonly textFileService: ITextFileService, - @IEditorService private readonly editorService: IEditorService - ) { - super(id, label); - } - - async run(event?: any, data?: ITelemetryData): Promise { - let resource: URI | undefined = toResource(this.editorService.activeEditor); - const options: ISaveOptions = { force: true, availableFileSystems: [Schemas.file] }; - if (resource) { - return this.textFileService.saveAs(resource, undefined, options); - } +export namespace SaveLocalFileCommand { + export const ID = 'workbench.action.files.saveLocalFile'; + export const LABEL = nls.localize('saveLocalFile', "Save Local File..."); + + export function handler(): ICommandHandler { + return accessor => { + const textFileService = accessor.get(ITextFileService); + const editorService = accessor.get(IEditorService); + let resource: URI | undefined = toResource(editorService.activeEditor); + const options: ISaveOptions = { force: true, availableFileSystems: [Schemas.file] }; + if (resource) { + return textFileService.saveAs(resource, undefined, options); + } + return Promise.resolve(undefined); + }; } } @@ -98,21 +87,15 @@ export class OpenFolderAction extends Action { } } -export class OpenLocalFolderAction extends Action { - - static readonly ID = 'workbench.action.files.openLocalFolder'; - static LABEL = nls.localize('openLocalFolder', "Open Local Folder..."); +export namespace OpenLocalFolderCommand { + export const ID = 'workbench.action.files.openLocalFolder'; + export const LABEL = nls.localize('openLocalFolder', "Open Local Folder..."); - constructor( - id: string, - label: string, - @IFileDialogService private readonly dialogService: IFileDialogService - ) { - super(id, label); - } - - run(event?: any, data?: ITelemetryData): Promise { - return this.dialogService.pickFolderAndOpen({ forceNewWindow: false, telemetryExtraData: data, availableFileSystems: [Schemas.file] }); + export function handler(): ICommandHandler { + return accessor => { + const dialogService = accessor.get(IFileDialogService); + return dialogService.pickFolderAndOpen({ forceNewWindow: false, availableFileSystems: [Schemas.file] }); + }; } } @@ -135,21 +118,16 @@ export class OpenFileFolderAction extends Action { } } -export class OpenLocalFileFolderAction extends Action { - - static readonly ID = 'workbench.action.files.openLocalFileFolder'; - static LABEL = nls.localize('openLocalFileFolder', "Open Local..."); +export namespace OpenLocalFileFolderCommand { - constructor( - id: string, - label: string, - @IFileDialogService private readonly dialogService: IFileDialogService - ) { - super(id, label); - } + export const ID = 'workbench.action.files.openLocalFileFolder'; + export const LABEL = nls.localize('openLocalFileFolder', "Open Local..."); - run(event?: any, data?: ITelemetryData): Promise { - return this.dialogService.pickFileFolderAndOpen({ forceNewWindow: false, telemetryExtraData: data, availableFileSystems: [Schemas.file] }); + export function handler(): ICommandHandler { + return accessor => { + const dialogService = accessor.get(IFileDialogService); + return dialogService.pickFileFolderAndOpen({ forceNewWindow: false, availableFileSystems: [Schemas.file] }); + }; } } diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 8573f02c5a2aa..6ebb9b3e3fec5 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -25,7 +25,7 @@ import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { SupportsWorkspacesContext, IsWebContext, RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { OpenFileFolderAction, OpenLocalFileFolderAction, OpenFileAction, OpenFolderAction, OpenLocalFileAction, OpenLocalFolderAction, OpenWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { OpenFileFolderAction, OpenLocalFileFolderCommand, OpenFileAction, OpenFolderAction, OpenLocalFileCommand, OpenLocalFolderCommand, OpenWorkspaceAction, SaveLocalFileCommand } from 'vs/workbench/browser/actions/workspaceActions'; // Contribute Global Actions const category = { value: nls.localize('filesCategory', "File"), original: 'File' }; @@ -48,17 +48,49 @@ const fileCategory = nls.localize('file', "File"); if (isMacintosh) { registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileFolderAction, OpenFileFolderAction.ID, OpenFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open...', fileCategory); if (!isWeb) { - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileFolderAction, OpenLocalFileFolderAction.ID, OpenLocalFileFolderAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local...', fileCategory); + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: OpenLocalFileFolderCommand.ID, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyCode.KEY_O, + when: RemoteFileDialogContext, + description: { description: OpenLocalFileFolderCommand.LABEL, args: [] }, + handler: OpenLocalFileFolderCommand.handler() + }); } } else { registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFileAction, OpenFileAction.ID, OpenFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }), 'File: Open File...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenFolderAction, OpenFolderAction.ID, OpenFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }), 'File: Open Folder...', fileCategory); if (!isWeb) { - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFileAction, OpenLocalFileAction.ID, OpenLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_O }, RemoteFileDialogContext), 'File: Open Local File...', fileCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(OpenLocalFolderAction, OpenLocalFolderAction.ID, OpenLocalFolderAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O) }, RemoteFileDialogContext), 'File: Open Local Folder...', fileCategory); + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: OpenLocalFileCommand.ID, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyCode.KEY_O, + when: RemoteFileDialogContext, + description: { description: OpenLocalFileCommand.LABEL, args: [] }, + handler: OpenLocalFileCommand.handler() + }); + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: OpenLocalFolderCommand.ID, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_O), + when: RemoteFileDialogContext, + description: { description: OpenLocalFolderCommand.LABEL, args: [] }, + handler: OpenLocalFolderCommand.handler() + }); } } +if (!isWeb) { + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: SaveLocalFileCommand.ID, + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_S, + when: RemoteFileDialogContext, + description: { description: SaveLocalFileCommand.LABEL, args: [] }, + handler: SaveLocalFileCommand.handler() + }); +} + const workspacesCategory = nls.localize('workspaces', "Workspaces"); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenWorkspaceAction, OpenWorkspaceAction.ID, OpenWorkspaceAction.LABEL), 'Workspaces: Open Workspace...', workspacesCategory, SupportsWorkspacesContext); diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index aa6647f914f6a..9b217d89457f1 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -14,14 +14,14 @@ import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; -import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ADD_ROOT_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; -import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext, RemoteFileDialogContext } from 'vs/workbench/browser/contextkeys'; +import { SupportsWorkspacesContext, IsMacContext, HasMacNativeTabsContext, IsDevelopmentContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys'; import { NoEditorsVisibleContext, SingleEditorGroupsContext } from 'vs/workbench/common/editor'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import { LogStorageAction } from 'vs/platform/storage/node/storageService'; @@ -35,7 +35,6 @@ import product from 'vs/platform/product/node/product'; (function registerFileActions(): void { const fileCategory = nls.localize('file', "File"); - registry.registerWorkbenchAction(new SyncActionDescriptor(SaveLocalFileAction, SaveLocalFileAction.ID, SaveLocalFileAction.LABEL, { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_S }, RemoteFileDialogContext), 'File: Save Local File...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(QuickOpenRecentAction, QuickOpenRecentAction.ID, QuickOpenRecentAction.LABEL), 'File: Quick Open Recent...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRecentAction, OpenRecentAction.ID, OpenRecentAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_R, mac: { primary: KeyMod.WinCtrl | KeyCode.KEY_R } }), 'File: Open Recent...', fileCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(CloseWorkspaceAction, CloseWorkspaceAction.ID, CloseWorkspaceAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'File: Close Workspace', fileCategory); diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index d40fb37930663..6a3b741424e4f 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -23,7 +23,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { equalsIgnoreCase, format, startsWithIgnoreCase } from 'vs/base/common/strings'; -import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction, SaveLocalFileAction } from 'vs/workbench/browser/actions/workspaceActions'; +import { OpenLocalFileCommand, OpenLocalFileFolderCommand, OpenLocalFolderCommand, SaveLocalFileCommand } from 'vs/workbench/browser/actions/workspaceActions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment'; import { isValidBasename } from 'vs/base/common/extpath'; @@ -217,9 +217,9 @@ export class RemoteFileDialog { this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local'); let action; if (isSave) { - action = SaveLocalFileAction; + action = SaveLocalFileCommand; } else { - action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderAction : OpenLocalFileAction) : OpenLocalFolderAction; + action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderCommand : OpenLocalFileCommand) : OpenLocalFolderCommand; } const keybinding = this.keybindingService.lookupKeybinding(action.ID); if (keybinding) { From df5f3f550c3ede60225d3043e77ae0f022806b05 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 24 Jun 2019 14:30:43 +0200 Subject: [PATCH 268/364] chockidar: use polling --- .../files/node/watcher/unix/chokidarWatcherService.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts b/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts index a95c7e4263242..2302d222f5796 100644 --- a/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts +++ b/src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts @@ -14,7 +14,7 @@ import { ThrottledDelayer } from 'vs/base/common/async'; import { normalizeNFC } from 'vs/base/common/normalization'; import { realcaseSync } from 'vs/base/node/extpath'; import { isMacintosh, isLinux } from 'vs/base/common/platform'; -import { IDiskFileChange, normalizeFileChanges, ILogMessage, isWSL1 } from 'vs/workbench/services/files/node/watcher/watcher'; +import { IDiskFileChange, normalizeFileChanges, ILogMessage } from 'vs/workbench/services/files/node/watcher/watcher'; import { IWatcherRequest, IWatcherService, IWatcherOptions } from 'vs/workbench/services/files/node/watcher/unix/watcher'; import { Emitter, Event } from 'vs/base/common/event'; @@ -36,6 +36,7 @@ export class ChokidarWatcherService implements IWatcherService { private _watcherCount: number; private _pollingInterval?: number; + private _usePolling?: boolean; private _verboseLogging: boolean; private spamCheckStartTime: number; @@ -50,6 +51,7 @@ export class ChokidarWatcherService implements IWatcherService { public watch(options: IWatcherOptions): Event { this._pollingInterval = options.pollingInterval; + this._usePolling = options.usePolling; this._watchers = Object.create(null); this._watcherCount = 0; return this.onWatchEvent; @@ -102,9 +104,9 @@ export class ChokidarWatcherService implements IWatcherService { } const pollingInterval = this._pollingInterval || 1000; - const usePolling = isWSL1(); + const usePolling = this._usePolling; if (usePolling && this._verboseLogging) { - this.log(`Use polling instead of fs.watch.`); + this.log(`Use polling instead of fs.watch: Polling interval ${pollingInterval} ms`); } const watcherOpts: chokidar.IOptions = { From 588fb230c33d401869b9d38a58104231c5e483af Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 24 Jun 2019 14:32:05 +0200 Subject: [PATCH 269/364] fix build conditions --- build/azure-pipelines/darwin/product-build-darwin.yml | 6 +++--- build/azure-pipelines/linux/product-build-linux-alpine.yml | 2 +- build/azure-pipelines/linux/product-build-linux-arm.yml | 2 +- build/azure-pipelines/linux/product-build-linux.yml | 4 ++-- build/azure-pipelines/win32/product-build-win32.yml | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 201a6bdce4ca6..b465ef9a09543 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -50,7 +50,7 @@ steps: yarn gulp hygiene yarn monaco-compile-check displayName: Run hygiene checks - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e @@ -72,13 +72,13 @@ steps: # APP_NAME="`ls $(agent.builddirectory)/VSCode-darwin | head -n 1`" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME" displayName: Run unit tests - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e ./scripts/test-integration.sh --build --tfs "Integration Tests" displayName: Run integration tests - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux-alpine.yml b/build/azure-pipelines/linux/product-build-linux-alpine.yml index 71dfb9206777e..107f7fa0cec73 100644 --- a/build/azure-pipelines/linux/product-build-linux-alpine.yml +++ b/build/azure-pipelines/linux/product-build-linux-alpine.yml @@ -59,7 +59,7 @@ steps: yarn gulp hygiene yarn monaco-compile-check displayName: Run hygiene checks - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux-arm.yml b/build/azure-pipelines/linux/product-build-linux-arm.yml index 8eb75c58aa9c3..ffa6d18f68e9d 100644 --- a/build/azure-pipelines/linux/product-build-linux-arm.yml +++ b/build/azure-pipelines/linux/product-build-linux-arm.yml @@ -59,7 +59,7 @@ steps: yarn gulp hygiene yarn monaco-compile-check displayName: Run hygiene checks - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 691851fbf977f..fa26c26dd1c63 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -51,7 +51,7 @@ steps: yarn gulp hygiene yarn monaco-compile-check displayName: Run hygiene checks - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e @@ -76,7 +76,7 @@ steps: DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)" displayName: Run unit tests - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - script: | set -e diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 6505b9a8df248..18758af4f997e 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -55,7 +55,7 @@ steps: exec { yarn gulp hygiene } exec { yarn monaco-compile-check } displayName: Run hygiene checks - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - powershell: | . build/azure-pipelines/win32/exec.ps1 @@ -78,7 +78,7 @@ steps: exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test.bat --build --tfs "Unit Tests" } displayName: Run unit tests - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - powershell: | . build/azure-pipelines/win32/exec.ps1 @@ -86,7 +86,7 @@ steps: exec { yarn gulp "electron-$(VSCODE_ARCH)" } exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" } displayName: Run integration tests - condition: eq(variables['VSCODE_STEP_ON_IT'], 'false') + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1 inputs: From 88f10ca5ed57020a92e09c5548bfd2d2cca96425 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 14:42:08 +0200 Subject: [PATCH 270/364] xterm fixes for cglicenses --- cglicenses.json | 1430 ++++++++++++++++++++++++----------------------- 1 file changed, 739 insertions(+), 691 deletions(-) diff --git a/cglicenses.json b/cglicenses.json index 3d96813f3ef1c..469cdedc9adec 100644 --- a/cglicenses.json +++ b/cglicenses.json @@ -6,694 +6,742 @@ // DO NOT EDIT THIS FILE UNLESS THE OSS TOOL INDICATES THAT YOU SHOULD. // [ -{ - // Reason: The license at https://github.com/aadsm/jschardet/blob/master/LICENSE - // does not include a clear Copyright statement and does not credit authors. - "name": "jschardet", - "licenseDetail": [ - "Chardet was originally ported from C++ by Mark Pilgrim. It is now maintained", - " by Dan Blanchard and Ian Cordasco, and was formerly maintained by Erik Rose.", - " JSChardet was ported from python to JavaScript by António Afonso ", - " (https://github.com/aadsm/jschardet) and transformed into an npm package by ", - "Markus Ast (https://github.com/brainafk)", - "", - "GNU LESSER GENERAL PUBLIC LICENSE", - "\t\t Version 2.1, February 1999", - "", - " Copyright (C) 1991,", - "1999 Free Software Foundation, Inc.", - " 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", - " Everyone is permitted to copy and distribute verbatim copies", - " of this license document, but changing it is not allowed.", - "", - "[This is the first released version of the Lesser GPL. It also counts", - " as the successor of the GNU Library Public License, version 2, hence", - " the version number 2.1.", - "]", - "", - "\t\t\t Preamble", - "", - " The licenses for most software are designed to take away your", - "freedom to share and change it. By contrast, the GNU General Public", - "Licenses are intended to guarantee your freedom to share and change", - "free software--to make sure the software is free for all its users.", - "", - " This license, the Lesser General Public License, applies to some", - "specially designated software packages--typically libraries--of the", - "Free Software Foundation and other authors who decide to use it. You", - "can use it too, but we suggest you first think carefully about whether", - "this license or the ordinary General Public License is the better", - "strategy to use in any particular case, based on the explanations below.", - "", - " When we speak of free software, we are referring to freedom of use,", - "not price. Our General Public Licenses are designed to make sure that", - "you have the freedom to distribute copies of free software (and charge", - "for this service if you wish); that you receive source code or can get", - "it if you want it; that you can change the software and use pieces of", - "it in new free programs; and that you are informed that you can do", - "these things.", - "", - " To protect your rights, we need to make restrictions that forbid", - "distributors to deny you these rights or to ask you to surrender these", - "rights. These restrictions translate to certain responsibilities for", - "you if you distribute copies of the library or if you modify it.", - "", - " For example, if you distribute copies of the library, whether gratis", - "or for a fee, you must give the recipients all the rights that we gave", - "you. You must make sure that they, too, receive or can get the source", - "code. If you link other code with the library, you must provide", - "complete object files to the recipients, so that they can relink them", - "with the library after making changes to the library and recompiling", - "it. And you must show them these terms so they know their rights.", - "", - " We protect your rights with a two-step method: (1) we copyright the", - "library, and (2) we offer you this license, which gives you legal", - "permission to copy, distribute and/or modify the library.", - "", - " To protect each distributor, we want to make it very clear that", - "there is no warranty for the free library. Also, if the library is", - "modified by someone else and passed on, the recipients should know", - "that what they have is not the original version, so that the original", - "author's reputation will not be affected by problems that might be", - "introduced by others.", - "", - " Finally, software patents pose a constant threat to the existence of", - "any free program. We wish to make sure that a company cannot", - "effectively restrict the users of a free program by obtaining a", - "restrictive license from a patent holder. Therefore, we insist that", - "any patent license obtained for a version of the library must be", - "consistent with the full freedom of use specified in this license.", - "", - " Most GNU software, including some libraries, is covered by the", - "ordinary GNU General Public License. This license, the GNU Lesser", - "General Public License, applies to certain designated libraries, and", - "is quite different from the ordinary General Public License. We use", - "this license for certain libraries in order to permit linking those", - "libraries into non-free programs.", - "", - " When a program is linked with a library, whether statically or using", - "a shared library, the combination of the two is legally speaking a", - "combined work, a derivative of the original library. The ordinary", - "General Public License therefore permits such linking only if the", - "entire combination fits its criteria of freedom. The Lesser General", - "Public License permits more lax criteria for linking other code with", - "the library.", - "", - " We call this license the \"Lesser\" General Public License because it", - "does Less to protect the user's freedom than the ordinary General", - "Public License. It also provides other free software developers Less", - "of an advantage over competing non-free programs. These disadvantages", - "are the reason we use the ordinary General Public License for many", - "libraries. However, the Lesser license provides advantages in certain", - "special circumstances.", - "", - " For example, on rare occasions, there may be a special need to", - "encourage the widest possible use of a certain library, so that it becomes", - "a de-facto standard. To achieve this, non-free programs must be", - "allowed to use the library. A more frequent case is that a free", - "library does the same job as widely used non-free libraries. In this", - "case, there is little to gain by limiting the free library to free", - "software only, so we use the Lesser General Public License.", - "", - " In other cases, permission to use a particular library in non-free", - "programs enables a greater number of people to use a large body of", - "free software. For example, permission to use the GNU C Library in", - "non-free programs enables many more people to use the whole GNU", - "operating system, as well as its variant, the GNU/Linux operating", - "system.", - "", - " Although the Lesser General Public License is Less protective of the", - "users' freedom, it does ensure that the user of a program that is", - "linked with the Library has the freedom and the wherewithal to run", - "that program using a modified version of the Library.", - "", - " The precise terms and conditions for copying, distribution and", - "modification follow. Pay close attention to the difference between a", - "\"work based on the library\" and a \"work that uses the library\". The", - "former contains code derived from the library, whereas the latter must", - "be combined with the library in order to run.", - "", - "\t\t GNU LESSER GENERAL PUBLIC LICENSE", - " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION", - "", - " 0. This License Agreement applies to any software library or other", - "program which contains a notice placed by the copyright holder or", - "other authorized party saying it may be distributed under the terms of", - "this Lesser General Public License (also called \"this License\").", - "Each licensee is addressed as \"you\".", - "", - " A \"library\" means a collection of software functions and/or data", - "prepared so as to be conveniently linked with application programs", - "(which use some of those functions and data) to form executables.", - "", - " The \"Library\", below, refers to any such software library or work", - "which has been distributed under these terms. A \"work based on the", - "Library\" means either the Library or any derivative work under", - "copyright law: that is to say, a work containing the Library or a", - "portion of it, either verbatim or with modifications and/or translated", - "straightforwardly into another language. (Hereinafter, translation is", - "included without limitation in the term \"modification\".)", - "", - " \"Source code\" for a work means the preferred form of the work for", - "making modifications to it. For a library, complete source code means", - "all the source code for all modules it contains, plus any associated", - "interface definition files, plus the scripts used to control compilation", - "and installation of the library.", - "", - " Activities other than copying, distribution and modification are not", - "covered by this License; they are outside its scope. The act of", - "running a program using the Library is not restricted, and output from", - "such a program is covered only if its contents constitute a work based", - "on the Library (independent of the use of the Library in a tool for", - "writing it). Whether that is true depends on what the Library does", - "and what the program that uses the Library does.", - "", - " 1. You may copy and distribute verbatim copies of the Library's", - "complete source code as you receive it, in any medium, provided that", - "you conspicuously and appropriately publish on each copy an", - "appropriate copyright notice and disclaimer of warranty; keep intact", - "all the notices that refer to this License and to the absence of any", - "warranty; and distribute a copy of this License along with the", - "Library.", - "", - " You may charge a fee for the physical act of transferring a copy,", - "and you may at your option offer warranty protection in exchange for a", - "fee.", - "", - " 2. You may modify your copy or copies of the Library or any portion", - "of it, thus forming a work based on the Library, and copy and", - "distribute such modifications or work under the terms of Section 1", - "above, provided that you also meet all of these conditions:", - "", - " a) The modified work must itself be a software library.", - "", - " b) You must cause the files modified to carry prominent notices", - " stating that you changed the files and the date of any change.", - "", - " c) You must cause the whole of the work to be licensed at no", - " charge to all third parties under the terms of this License.", - "", - " d) If a facility in the modified Library refers to a function or a", - " table of data to be supplied by an application program that uses", - " the facility, other than as an argument passed when the facility", - " is invoked, then you must make a good faith effort to ensure that,", - " in the event an application does not supply such function or", - " table, the facility still operates, and performs whatever part of", - " its purpose remains meaningful.", - "", - " (For example, a function in a library to compute square roots has", - " a purpose that is entirely well-defined independent of the", - " application. Therefore, Subsection 2d requires that any", - " application-supplied function or table used by this function must", - " be optional: if the application does not supply it, the square", - " root function must still compute square roots.)", - "", - "These requirements apply to the modified work as a whole. If", - "identifiable sections of that work are not derived from the Library,", - "and can be reasonably considered independent and separate works in", - "themselves, then this License, and its terms, do not apply to those", - "sections when you distribute them as separate works. But when you", - "distribute the same sections as part of a whole which is a work based", - "on the Library, the distribution of the whole must be on the terms of", - "this License, whose permissions for other licensees extend to the", - "entire whole, and thus to each and every part regardless of who wrote", - "it.", - "", - "Thus, it is not the intent of this section to claim rights or contest", - "your rights to work written entirely by you; rather, the intent is to", - "exercise the right to control the distribution of derivative or", - "collective works based on the Library.", - "", - "In addition, mere aggregation of another work not based on the Library", - "with the Library (or with a work based on the Library) on a volume of", - "a storage or distribution medium does not bring the other work under", - "the scope of this License.", - "", - " 3. You may opt to apply the terms of the ordinary GNU General Public", - "License instead of this License to a given copy of the Library. To do", - "this, you must alter all the notices that refer to this License, so", - "that they refer to the ordinary GNU General Public License, version 2,", - "instead of to this License. (If a newer version than version 2 of the", - "ordinary GNU General Public License has appeared, then you can specify", - "that version instead if you wish.) Do not make any other change in", - "these notices.", - "", - " Once this change is made in a given copy, it is irreversible for", - "that copy, so the ordinary GNU General Public License applies to all", - "subsequent copies and derivative works made from that copy.", - "", - " This option is useful when you wish to copy part of the code of", - "the Library into a program that is not a library.", - "", - " 4. You may copy and distribute the Library (or a portion or", - "derivative of it, under Section 2) in object code or executable form", - "under the terms of Sections 1 and 2 above provided that you accompany", - "it with the complete corresponding machine-readable source code, which", - "must be distributed under the terms of Sections 1 and 2 above on a", - "medium customarily used for software interchange.", - "", - " If distribution of object code is made by offering access to copy", - "from a designated place, then offering equivalent access to copy the", - "source code from the same place satisfies the requirement to", - "distribute the source code, even though third parties are not", - "compelled to copy the source along with the object code.", - "", - " 5. A program that contains no derivative of any portion of the", - "Library, but is designed to work with the Library by being compiled or", - "linked with it, is called a \"work that uses the Library\". Such a", - "work, in isolation, is not a derivative work of the Library, and", - "therefore falls outside the scope of this License.", - "", - " However, linking a \"work that uses the Library\" with the Library", - "creates an executable that is a derivative of the Library (because it", - "contains portions of the Library), rather than a \"work that uses the", - "library\". The executable is therefore covered by this License.", - "Section 6 states terms for distribution of such executables.", - "", - " When a \"work that uses the Library\" uses material from a header file", - "that is part of the Library, the object code for the work may be a", - "derivative work of the Library even though the source code is not.", - "Whether this is true is especially significant if the work can be", - "linked without the Library, or if the work is itself a library. The", - "threshold for this to be true is not precisely defined by law.", - "", - " If such an object file uses only numerical parameters, data", - "structure layouts and accessors, and small macros and small inline", - "functions (ten lines or less in length), then the use of the object", - "file is unrestricted, regardless of whether it is legally a derivative", - "work. (Executables containing this object code plus portions of the", - "Library will still fall under Section 6.)", - "", - " Otherwise, if the work is a derivative of the Library, you may", - "distribute the object code for the work under the terms of Section 6.", - "Any executables containing that work also fall under Section 6,", - "whether or not they are linked directly with the Library itself.", - "", - " 6. As an exception to the Sections above, you may also combine or", - "link a \"work that uses the Library\" with the Library to produce a", - "work containing portions of the Library, and distribute that work", - "under terms of your choice, provided that the terms permit", - "modification of the work for the customer's own use and reverse", - "engineering for debugging such modifications.", - "", - " You must give prominent notice with each copy of the work that the", - "Library is used in it and that the Library and its use are covered by", - "this License. You must supply a copy of this License. If the work", - "during execution displays copyright notices, you must include the", - "copyright notice for the Library among them, as well as a reference", - "directing the user to the copy of this License. Also, you must do one", - "of these things:", - "", - " a) Accompany the work with the complete corresponding", - " machine-readable source code for the Library including whatever", - " changes were used in the work (which must be distributed under", - " Sections 1 and 2 above); and, if the work is an executable linked", - " with the Library, with the complete machine-readable \"work that", - " uses the Library\", as object code and/or source code, so that the", - " user can modify the Library and then relink to produce a modified", - " executable containing the modified Library. (It is understood", - " that the user who changes the contents of definitions files in the", - " Library will not necessarily be able to recompile the application", - " to use the modified definitions.)", - "", - " b) Use a suitable shared library mechanism for linking with the", - " Library. A suitable mechanism is one that (1) uses at run time a", - " copy of the library already present on the user's computer system,", - " rather than copying library functions into the executable, and (2)", - " will operate properly with a modified version of the library, if", - " the user installs one, as long as the modified version is", - " interface-compatible with the version that the work was made with.", - "", - " c) Accompany the work with a written offer, valid for at", - " least three years, to give the same user the materials", - " specified in Subsection 6a, above, for a charge no more", - " than the cost of performing this distribution.", - "", - " d) If distribution of the work is made by offering access to copy", - " from a designated place, offer equivalent access to copy the above", - " specified materials from the same place.", - "", - " e) Verify that the user has already received a copy of these", - " materials or that you have already sent this user a copy.", - "", - " For an executable, the required form of the \"work that uses the", - "Library\" must include any data and utility programs needed for", - "reproducing the executable from it. However, as a special exception,", - "the materials to be distributed need not include anything that is", - "normally distributed (in either source or binary form) with the major", - "components (compiler, kernel, and so on) of the operating system on", - "which the executable runs, unless that component itself accompanies", - "the executable.", - "", - " It may happen that this requirement contradicts the license", - "restrictions of other proprietary libraries that do not normally", - "accompany the operating system. Such a contradiction means you cannot", - "use both them and the Library together in an executable that you", - "distribute.", - "", - " 7. You may place library facilities that are a work based on the", - "Library side-by-side in a single library together with other library", - "facilities not covered by this License, and distribute such a combined", - "library, provided that the separate distribution of the work based on", - "the Library and of the other library facilities is otherwise", - "permitted, and provided that you do these two things:", - "", - " a) Accompany the combined library with a copy of the same work", - " based on the Library, uncombined with any other library", - " facilities. This must be distributed under the terms of the", - " Sections above.", - "", - " b) Give prominent notice with the combined library of the fact", - " that part of it is a work based on the Library, and explaining", - " where to find the accompanying uncombined form of the same work.", - "", - " 8. You may not copy, modify, sublicense, link with, or distribute", - "the Library except as expressly provided under this License. Any", - "attempt otherwise to copy, modify, sublicense, link with, or", - "distribute the Library is void, and will automatically terminate your", - "rights under this License. However, parties who have received copies,", - "or rights, from you under this License will not have their licenses", - "terminated so long as such parties remain in full compliance.", - "", - " 9. You are not required to accept this License, since you have not", - "signed it. However, nothing else grants you permission to modify or", - "distribute the Library or its derivative works. These actions are", - "prohibited by law if you do not accept this License. Therefore, by", - "modifying or distributing the Library (or any work based on the", - "Library), you indicate your acceptance of this License to do so, and", - "all its terms and conditions for copying, distributing or modifying", - "the Library or works based on it.", - "", - " 10. Each time you redistribute the Library (or any work based on the", - "Library), the recipient automatically receives a license from the", - "original licensor to copy, distribute, link with or modify the Library", - "subject to these terms and conditions. You may not impose any further", - "restrictions on the recipients' exercise of the rights granted herein.", - "You are not responsible for enforcing compliance by third parties with", - "this License.", - "", - " 11. If, as a consequence of a court judgment or allegation of patent", - "infringement or for any other reason (not limited to patent issues),", - "conditions are imposed on you (whether by court order, agreement or", - "otherwise) that contradict the conditions of this License, they do not", - "excuse you from the conditions of this License. If you cannot", - "distribute so as to satisfy simultaneously your obligations under this", - "License and any other pertinent obligations, then as a consequence you", - "may not distribute the Library at all. For example, if a patent", - "license would not permit royalty-free redistribution of the Library by", - "all those who receive copies directly or indirectly through you, then", - "the only way you could satisfy both it and this License would be to", - "refrain entirely from distribution of the Library.", - "", - "If any portion of this section is held invalid or unenforceable under any", - "particular circumstance, the balance of the section is intended to apply,", - "and the section as a whole is intended to apply in other circumstances.", - "", - "It is not the purpose of this section to induce you to infringe any", - "patents or other property right claims or to contest validity of any", - "such claims; this section has the sole purpose of protecting the", - "integrity of the free software distribution system which is", - "implemented by public license practices. Many people have made", - "generous contributions to the wide range of software distributed", - "through that system in reliance on consistent application of that", - "system; it is up to the author/donor to decide if he or she is willing", - "to distribute software through any other system and a licensee cannot", - "impose that choice.", - "", - "This section is intended to make thoroughly clear what is believed to", - "be a consequence of the rest of this License.", - "", - " 12. If the distribution and/or use of the Library is restricted in", - "certain countries either by patents or by copyrighted interfaces, the", - "original copyright holder who places the Library under this License may add", - "an explicit geographical distribution limitation excluding those countries,", - "so that distribution is permitted only in or among countries not thus", - "excluded. In such case, this License incorporates the limitation as if", - "written in the body of this License.", - "", - " 13. The Free Software Foundation may publish revised and/or new", - "versions of the Lesser General Public License from time to time.", - "Such new versions will be similar in spirit to the present version,", - "but may differ in detail to address new problems or concerns.", - "", - "Each version is given a distinguishing version number. If the Library", - "specifies a version number of this License which applies to it and", - "\"any later version\", you have the option of following the terms and", - "conditions either of that version or of any later version published by", - "the Free Software Foundation. If the Library does not specify a", - "license version number, you may choose any version ever published by", - "the Free Software Foundation.", - "", - " 14. If you wish to incorporate parts of the Library into other free", - "programs whose distribution conditions are incompatible with these,", - "write to the author to ask for permission. For software which is", - "copyrighted by the Free Software Foundation, write to the Free", - "Software Foundation; we sometimes make exceptions for this. Our", - "decision will be guided by the two goals of preserving the free status", - "of all derivatives of our free software and of promoting the sharing", - "and reuse of software generally.", - "", - "\t\t\t NO WARRANTY", - "", - " 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO", - "WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.", - "EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR", - "OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY", - "KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE", - "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", - "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE", - "LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME", - "THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.", - "", - " 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN", - "WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY", - "AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU", - "FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR", - "CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE", - "LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING", - "RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A", - "FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF", - "SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH", - "DAMAGES.", - "", - "\t\t END OF TERMS AND CONDITIONS", - "", - " How to Apply These Terms to Your New Libraries", - "", - " If you develop a new library, and you want it to be of the greatest", - "possible use to the public, we recommend making it free software that", - "everyone can redistribute and change. You can do so by permitting", - "redistribution under these terms (or, alternatively, under the terms of the", - "ordinary General Public License).", - "", - " To apply these terms, attach the following notices to the library. It is", - "safest to attach them to the start of each source file to most effectively", - "convey the exclusion of warranty; and each file should have at least the", - "\"copyright\" line and a pointer to where the full notice is found.", - "", - " ", - " Copyright (C) ", - "", - " This library is free software; you can redistribute it and/or", - " modify it under the terms of the GNU Lesser General Public", - " License as published by the Free Software Foundation; either", - " version 2.1 of the License, or (at your option) any later version.", - "", - " This library is distributed in the hope that it will be useful,", - " but WITHOUT ANY WARRANTY; without even the implied warranty of", - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU", - " Lesser General Public License for more details.", - "", - " You should have received a copy of the GNU Lesser General Public", - " License along with this library; if not, write to the Free Software", - " Foundation, Inc.,", - "51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", - "", - "Also add information on how to contact you by electronic and paper mail.", - "", - "You should also get your employer (if you work as a programmer) or your", - "school, if any, to sign a \"copyright disclaimer\" for the library, if", - "necessary. Here is a sample; alter the names:", - "", - " Yoyodyne, Inc., hereby disclaims all copyright interest in the", - " library `Frob' (a library for tweaking knobs) written by James Random Hacker.", - "", - " ,", - "1 April 1990", - " Ty Coon, President of Vice", - "", - "That's all there is to it!" - ] -}, -{ - // Added here because the module `parse5` has a dependency to it. - // The module `parse5` is shipped via the `extension-editing` built-in extension. - // The module `parse5` does not want to remove it https://github.com/inikulin/parse5/issues/225 - "name": "@types/node", - "licenseDetail": [ - "This project is licensed under the MIT license.", - "Copyrights are respective of each contributor listed at the beginning of each definition file.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] -}, -{ - // We override the license that gets discovered at - // https://github.com/Microsoft/TypeScript/blob/master/LICENSE.txt - // because it does not contain a Copyright statement - "name": "typescript", - "licenseDetail": [ - "Copyright (c) Microsoft Corporation. All rights reserved.", - "", - "Apache License", - "", - "Version 2.0, January 2004", - "", - "http://www.apache.org/licenses/", - "", - "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", - "", - "1. Definitions.", - "", - "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", - "", - "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", - "", - "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", - "", - "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", - "", - "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", - "", - "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", - "", - "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", - "", - "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", - "", - "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", - "", - "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", - "", - "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", - "", - "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", - "", - "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", - "", - "You must give any other recipients of the Work or Derivative Works a copy of this License; and", - "", - "You must cause any modified files to carry prominent notices stating that You changed the files; and", - "", - "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", - "", - "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", - "", - "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", - "", - "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", - "", - "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", - "", - "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", - "", - "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", - "", - "END OF TERMS AND CONDITIONS" - ] -}, -{ - // This module comes in from https://github.com/Microsoft/vscode-node-debug2/blob/master/package-lock.json - "name": "@types/source-map", - "licenseDetail": [ - "This project is licensed under the MIT license.", - "Copyrights are respective of each contributor listed at the beginning of each definition file.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] -}, -{ - "name": "tunnel-agent", - "licenseDetail": [ - "Copyright (c) tunnel-agent authors", - "", - "Apache License", - "", - "Version 2.0, January 2004", - "", - "http://www.apache.org/licenses/", - "", - "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", - "", - "1. Definitions.", - "", - "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", - "", - "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", - "", - "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", - "", - "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", - "", - "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", - "", - "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", - "", - "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", - "", - "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", - "", - "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", - "", - "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", - "", - "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", - "", - "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", - "", - "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", - "", - "You must give any other recipients of the Work or Derivative Works a copy of this License; and", - "", - "You must cause any modified files to carry prominent notices stating that You changed the files; and", - "", - "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", - "", - "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", - "", - "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", - "", - "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", - "", - "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", - "", - "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", - "", - "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", - "", - "END OF TERMS AND CONDITIONS" - ] -}, -{ - // Waiting for https://github.com/segmentio/noop-logger/issues/2 - "name": "noop-logger", - "licenseDetail": [ - "This project is licensed under the MIT license.", - "Copyrights are respective of each contributor listed at the beginning of each definition file.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." - ] -} -] \ No newline at end of file + { + // Reason: The license at https://github.com/aadsm/jschardet/blob/master/LICENSE + // does not include a clear Copyright statement and does not credit authors. + "name": "jschardet", + "licenseDetail": [ + "Chardet was originally ported from C++ by Mark Pilgrim. It is now maintained", + " by Dan Blanchard and Ian Cordasco, and was formerly maintained by Erik Rose.", + " JSChardet was ported from python to JavaScript by António Afonso ", + " (https://github.com/aadsm/jschardet) and transformed into an npm package by ", + "Markus Ast (https://github.com/brainafk)", + "", + "GNU LESSER GENERAL PUBLIC LICENSE", + "\t\t Version 2.1, February 1999", + "", + " Copyright (C) 1991,", + "1999 Free Software Foundation, Inc.", + " 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", + " Everyone is permitted to copy and distribute verbatim copies", + " of this license document, but changing it is not allowed.", + "", + "[This is the first released version of the Lesser GPL. It also counts", + " as the successor of the GNU Library Public License, version 2, hence", + " the version number 2.1.", + "]", + "", + "\t\t\t Preamble", + "", + " The licenses for most software are designed to take away your", + "freedom to share and change it. By contrast, the GNU General Public", + "Licenses are intended to guarantee your freedom to share and change", + "free software--to make sure the software is free for all its users.", + "", + " This license, the Lesser General Public License, applies to some", + "specially designated software packages--typically libraries--of the", + "Free Software Foundation and other authors who decide to use it. You", + "can use it too, but we suggest you first think carefully about whether", + "this license or the ordinary General Public License is the better", + "strategy to use in any particular case, based on the explanations below.", + "", + " When we speak of free software, we are referring to freedom of use,", + "not price. Our General Public Licenses are designed to make sure that", + "you have the freedom to distribute copies of free software (and charge", + "for this service if you wish); that you receive source code or can get", + "it if you want it; that you can change the software and use pieces of", + "it in new free programs; and that you are informed that you can do", + "these things.", + "", + " To protect your rights, we need to make restrictions that forbid", + "distributors to deny you these rights or to ask you to surrender these", + "rights. These restrictions translate to certain responsibilities for", + "you if you distribute copies of the library or if you modify it.", + "", + " For example, if you distribute copies of the library, whether gratis", + "or for a fee, you must give the recipients all the rights that we gave", + "you. You must make sure that they, too, receive or can get the source", + "code. If you link other code with the library, you must provide", + "complete object files to the recipients, so that they can relink them", + "with the library after making changes to the library and recompiling", + "it. And you must show them these terms so they know their rights.", + "", + " We protect your rights with a two-step method: (1) we copyright the", + "library, and (2) we offer you this license, which gives you legal", + "permission to copy, distribute and/or modify the library.", + "", + " To protect each distributor, we want to make it very clear that", + "there is no warranty for the free library. Also, if the library is", + "modified by someone else and passed on, the recipients should know", + "that what they have is not the original version, so that the original", + "author's reputation will not be affected by problems that might be", + "introduced by others.", + "", + " Finally, software patents pose a constant threat to the existence of", + "any free program. We wish to make sure that a company cannot", + "effectively restrict the users of a free program by obtaining a", + "restrictive license from a patent holder. Therefore, we insist that", + "any patent license obtained for a version of the library must be", + "consistent with the full freedom of use specified in this license.", + "", + " Most GNU software, including some libraries, is covered by the", + "ordinary GNU General Public License. This license, the GNU Lesser", + "General Public License, applies to certain designated libraries, and", + "is quite different from the ordinary General Public License. We use", + "this license for certain libraries in order to permit linking those", + "libraries into non-free programs.", + "", + " When a program is linked with a library, whether statically or using", + "a shared library, the combination of the two is legally speaking a", + "combined work, a derivative of the original library. The ordinary", + "General Public License therefore permits such linking only if the", + "entire combination fits its criteria of freedom. The Lesser General", + "Public License permits more lax criteria for linking other code with", + "the library.", + "", + " We call this license the \"Lesser\" General Public License because it", + "does Less to protect the user's freedom than the ordinary General", + "Public License. It also provides other free software developers Less", + "of an advantage over competing non-free programs. These disadvantages", + "are the reason we use the ordinary General Public License for many", + "libraries. However, the Lesser license provides advantages in certain", + "special circumstances.", + "", + " For example, on rare occasions, there may be a special need to", + "encourage the widest possible use of a certain library, so that it becomes", + "a de-facto standard. To achieve this, non-free programs must be", + "allowed to use the library. A more frequent case is that a free", + "library does the same job as widely used non-free libraries. In this", + "case, there is little to gain by limiting the free library to free", + "software only, so we use the Lesser General Public License.", + "", + " In other cases, permission to use a particular library in non-free", + "programs enables a greater number of people to use a large body of", + "free software. For example, permission to use the GNU C Library in", + "non-free programs enables many more people to use the whole GNU", + "operating system, as well as its variant, the GNU/Linux operating", + "system.", + "", + " Although the Lesser General Public License is Less protective of the", + "users' freedom, it does ensure that the user of a program that is", + "linked with the Library has the freedom and the wherewithal to run", + "that program using a modified version of the Library.", + "", + " The precise terms and conditions for copying, distribution and", + "modification follow. Pay close attention to the difference between a", + "\"work based on the library\" and a \"work that uses the library\". The", + "former contains code derived from the library, whereas the latter must", + "be combined with the library in order to run.", + "", + "\t\t GNU LESSER GENERAL PUBLIC LICENSE", + " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION", + "", + " 0. This License Agreement applies to any software library or other", + "program which contains a notice placed by the copyright holder or", + "other authorized party saying it may be distributed under the terms of", + "this Lesser General Public License (also called \"this License\").", + "Each licensee is addressed as \"you\".", + "", + " A \"library\" means a collection of software functions and/or data", + "prepared so as to be conveniently linked with application programs", + "(which use some of those functions and data) to form executables.", + "", + " The \"Library\", below, refers to any such software library or work", + "which has been distributed under these terms. A \"work based on the", + "Library\" means either the Library or any derivative work under", + "copyright law: that is to say, a work containing the Library or a", + "portion of it, either verbatim or with modifications and/or translated", + "straightforwardly into another language. (Hereinafter, translation is", + "included without limitation in the term \"modification\".)", + "", + " \"Source code\" for a work means the preferred form of the work for", + "making modifications to it. For a library, complete source code means", + "all the source code for all modules it contains, plus any associated", + "interface definition files, plus the scripts used to control compilation", + "and installation of the library.", + "", + " Activities other than copying, distribution and modification are not", + "covered by this License; they are outside its scope. The act of", + "running a program using the Library is not restricted, and output from", + "such a program is covered only if its contents constitute a work based", + "on the Library (independent of the use of the Library in a tool for", + "writing it). Whether that is true depends on what the Library does", + "and what the program that uses the Library does.", + "", + " 1. You may copy and distribute verbatim copies of the Library's", + "complete source code as you receive it, in any medium, provided that", + "you conspicuously and appropriately publish on each copy an", + "appropriate copyright notice and disclaimer of warranty; keep intact", + "all the notices that refer to this License and to the absence of any", + "warranty; and distribute a copy of this License along with the", + "Library.", + "", + " You may charge a fee for the physical act of transferring a copy,", + "and you may at your option offer warranty protection in exchange for a", + "fee.", + "", + " 2. You may modify your copy or copies of the Library or any portion", + "of it, thus forming a work based on the Library, and copy and", + "distribute such modifications or work under the terms of Section 1", + "above, provided that you also meet all of these conditions:", + "", + " a) The modified work must itself be a software library.", + "", + " b) You must cause the files modified to carry prominent notices", + " stating that you changed the files and the date of any change.", + "", + " c) You must cause the whole of the work to be licensed at no", + " charge to all third parties under the terms of this License.", + "", + " d) If a facility in the modified Library refers to a function or a", + " table of data to be supplied by an application program that uses", + " the facility, other than as an argument passed when the facility", + " is invoked, then you must make a good faith effort to ensure that,", + " in the event an application does not supply such function or", + " table, the facility still operates, and performs whatever part of", + " its purpose remains meaningful.", + "", + " (For example, a function in a library to compute square roots has", + " a purpose that is entirely well-defined independent of the", + " application. Therefore, Subsection 2d requires that any", + " application-supplied function or table used by this function must", + " be optional: if the application does not supply it, the square", + " root function must still compute square roots.)", + "", + "These requirements apply to the modified work as a whole. If", + "identifiable sections of that work are not derived from the Library,", + "and can be reasonably considered independent and separate works in", + "themselves, then this License, and its terms, do not apply to those", + "sections when you distribute them as separate works. But when you", + "distribute the same sections as part of a whole which is a work based", + "on the Library, the distribution of the whole must be on the terms of", + "this License, whose permissions for other licensees extend to the", + "entire whole, and thus to each and every part regardless of who wrote", + "it.", + "", + "Thus, it is not the intent of this section to claim rights or contest", + "your rights to work written entirely by you; rather, the intent is to", + "exercise the right to control the distribution of derivative or", + "collective works based on the Library.", + "", + "In addition, mere aggregation of another work not based on the Library", + "with the Library (or with a work based on the Library) on a volume of", + "a storage or distribution medium does not bring the other work under", + "the scope of this License.", + "", + " 3. You may opt to apply the terms of the ordinary GNU General Public", + "License instead of this License to a given copy of the Library. To do", + "this, you must alter all the notices that refer to this License, so", + "that they refer to the ordinary GNU General Public License, version 2,", + "instead of to this License. (If a newer version than version 2 of the", + "ordinary GNU General Public License has appeared, then you can specify", + "that version instead if you wish.) Do not make any other change in", + "these notices.", + "", + " Once this change is made in a given copy, it is irreversible for", + "that copy, so the ordinary GNU General Public License applies to all", + "subsequent copies and derivative works made from that copy.", + "", + " This option is useful when you wish to copy part of the code of", + "the Library into a program that is not a library.", + "", + " 4. You may copy and distribute the Library (or a portion or", + "derivative of it, under Section 2) in object code or executable form", + "under the terms of Sections 1 and 2 above provided that you accompany", + "it with the complete corresponding machine-readable source code, which", + "must be distributed under the terms of Sections 1 and 2 above on a", + "medium customarily used for software interchange.", + "", + " If distribution of object code is made by offering access to copy", + "from a designated place, then offering equivalent access to copy the", + "source code from the same place satisfies the requirement to", + "distribute the source code, even though third parties are not", + "compelled to copy the source along with the object code.", + "", + " 5. A program that contains no derivative of any portion of the", + "Library, but is designed to work with the Library by being compiled or", + "linked with it, is called a \"work that uses the Library\". Such a", + "work, in isolation, is not a derivative work of the Library, and", + "therefore falls outside the scope of this License.", + "", + " However, linking a \"work that uses the Library\" with the Library", + "creates an executable that is a derivative of the Library (because it", + "contains portions of the Library), rather than a \"work that uses the", + "library\". The executable is therefore covered by this License.", + "Section 6 states terms for distribution of such executables.", + "", + " When a \"work that uses the Library\" uses material from a header file", + "that is part of the Library, the object code for the work may be a", + "derivative work of the Library even though the source code is not.", + "Whether this is true is especially significant if the work can be", + "linked without the Library, or if the work is itself a library. The", + "threshold for this to be true is not precisely defined by law.", + "", + " If such an object file uses only numerical parameters, data", + "structure layouts and accessors, and small macros and small inline", + "functions (ten lines or less in length), then the use of the object", + "file is unrestricted, regardless of whether it is legally a derivative", + "work. (Executables containing this object code plus portions of the", + "Library will still fall under Section 6.)", + "", + " Otherwise, if the work is a derivative of the Library, you may", + "distribute the object code for the work under the terms of Section 6.", + "Any executables containing that work also fall under Section 6,", + "whether or not they are linked directly with the Library itself.", + "", + " 6. As an exception to the Sections above, you may also combine or", + "link a \"work that uses the Library\" with the Library to produce a", + "work containing portions of the Library, and distribute that work", + "under terms of your choice, provided that the terms permit", + "modification of the work for the customer's own use and reverse", + "engineering for debugging such modifications.", + "", + " You must give prominent notice with each copy of the work that the", + "Library is used in it and that the Library and its use are covered by", + "this License. You must supply a copy of this License. If the work", + "during execution displays copyright notices, you must include the", + "copyright notice for the Library among them, as well as a reference", + "directing the user to the copy of this License. Also, you must do one", + "of these things:", + "", + " a) Accompany the work with the complete corresponding", + " machine-readable source code for the Library including whatever", + " changes were used in the work (which must be distributed under", + " Sections 1 and 2 above); and, if the work is an executable linked", + " with the Library, with the complete machine-readable \"work that", + " uses the Library\", as object code and/or source code, so that the", + " user can modify the Library and then relink to produce a modified", + " executable containing the modified Library. (It is understood", + " that the user who changes the contents of definitions files in the", + " Library will not necessarily be able to recompile the application", + " to use the modified definitions.)", + "", + " b) Use a suitable shared library mechanism for linking with the", + " Library. A suitable mechanism is one that (1) uses at run time a", + " copy of the library already present on the user's computer system,", + " rather than copying library functions into the executable, and (2)", + " will operate properly with a modified version of the library, if", + " the user installs one, as long as the modified version is", + " interface-compatible with the version that the work was made with.", + "", + " c) Accompany the work with a written offer, valid for at", + " least three years, to give the same user the materials", + " specified in Subsection 6a, above, for a charge no more", + " than the cost of performing this distribution.", + "", + " d) If distribution of the work is made by offering access to copy", + " from a designated place, offer equivalent access to copy the above", + " specified materials from the same place.", + "", + " e) Verify that the user has already received a copy of these", + " materials or that you have already sent this user a copy.", + "", + " For an executable, the required form of the \"work that uses the", + "Library\" must include any data and utility programs needed for", + "reproducing the executable from it. However, as a special exception,", + "the materials to be distributed need not include anything that is", + "normally distributed (in either source or binary form) with the major", + "components (compiler, kernel, and so on) of the operating system on", + "which the executable runs, unless that component itself accompanies", + "the executable.", + "", + " It may happen that this requirement contradicts the license", + "restrictions of other proprietary libraries that do not normally", + "accompany the operating system. Such a contradiction means you cannot", + "use both them and the Library together in an executable that you", + "distribute.", + "", + " 7. You may place library facilities that are a work based on the", + "Library side-by-side in a single library together with other library", + "facilities not covered by this License, and distribute such a combined", + "library, provided that the separate distribution of the work based on", + "the Library and of the other library facilities is otherwise", + "permitted, and provided that you do these two things:", + "", + " a) Accompany the combined library with a copy of the same work", + " based on the Library, uncombined with any other library", + " facilities. This must be distributed under the terms of the", + " Sections above.", + "", + " b) Give prominent notice with the combined library of the fact", + " that part of it is a work based on the Library, and explaining", + " where to find the accompanying uncombined form of the same work.", + "", + " 8. You may not copy, modify, sublicense, link with, or distribute", + "the Library except as expressly provided under this License. Any", + "attempt otherwise to copy, modify, sublicense, link with, or", + "distribute the Library is void, and will automatically terminate your", + "rights under this License. However, parties who have received copies,", + "or rights, from you under this License will not have their licenses", + "terminated so long as such parties remain in full compliance.", + "", + " 9. You are not required to accept this License, since you have not", + "signed it. However, nothing else grants you permission to modify or", + "distribute the Library or its derivative works. These actions are", + "prohibited by law if you do not accept this License. Therefore, by", + "modifying or distributing the Library (or any work based on the", + "Library), you indicate your acceptance of this License to do so, and", + "all its terms and conditions for copying, distributing or modifying", + "the Library or works based on it.", + "", + " 10. Each time you redistribute the Library (or any work based on the", + "Library), the recipient automatically receives a license from the", + "original licensor to copy, distribute, link with or modify the Library", + "subject to these terms and conditions. You may not impose any further", + "restrictions on the recipients' exercise of the rights granted herein.", + "You are not responsible for enforcing compliance by third parties with", + "this License.", + "", + " 11. If, as a consequence of a court judgment or allegation of patent", + "infringement or for any other reason (not limited to patent issues),", + "conditions are imposed on you (whether by court order, agreement or", + "otherwise) that contradict the conditions of this License, they do not", + "excuse you from the conditions of this License. If you cannot", + "distribute so as to satisfy simultaneously your obligations under this", + "License and any other pertinent obligations, then as a consequence you", + "may not distribute the Library at all. For example, if a patent", + "license would not permit royalty-free redistribution of the Library by", + "all those who receive copies directly or indirectly through you, then", + "the only way you could satisfy both it and this License would be to", + "refrain entirely from distribution of the Library.", + "", + "If any portion of this section is held invalid or unenforceable under any", + "particular circumstance, the balance of the section is intended to apply,", + "and the section as a whole is intended to apply in other circumstances.", + "", + "It is not the purpose of this section to induce you to infringe any", + "patents or other property right claims or to contest validity of any", + "such claims; this section has the sole purpose of protecting the", + "integrity of the free software distribution system which is", + "implemented by public license practices. Many people have made", + "generous contributions to the wide range of software distributed", + "through that system in reliance on consistent application of that", + "system; it is up to the author/donor to decide if he or she is willing", + "to distribute software through any other system and a licensee cannot", + "impose that choice.", + "", + "This section is intended to make thoroughly clear what is believed to", + "be a consequence of the rest of this License.", + "", + " 12. If the distribution and/or use of the Library is restricted in", + "certain countries either by patents or by copyrighted interfaces, the", + "original copyright holder who places the Library under this License may add", + "an explicit geographical distribution limitation excluding those countries,", + "so that distribution is permitted only in or among countries not thus", + "excluded. In such case, this License incorporates the limitation as if", + "written in the body of this License.", + "", + " 13. The Free Software Foundation may publish revised and/or new", + "versions of the Lesser General Public License from time to time.", + "Such new versions will be similar in spirit to the present version,", + "but may differ in detail to address new problems or concerns.", + "", + "Each version is given a distinguishing version number. If the Library", + "specifies a version number of this License which applies to it and", + "\"any later version\", you have the option of following the terms and", + "conditions either of that version or of any later version published by", + "the Free Software Foundation. If the Library does not specify a", + "license version number, you may choose any version ever published by", + "the Free Software Foundation.", + "", + " 14. If you wish to incorporate parts of the Library into other free", + "programs whose distribution conditions are incompatible with these,", + "write to the author to ask for permission. For software which is", + "copyrighted by the Free Software Foundation, write to the Free", + "Software Foundation; we sometimes make exceptions for this. Our", + "decision will be guided by the two goals of preserving the free status", + "of all derivatives of our free software and of promoting the sharing", + "and reuse of software generally.", + "", + "\t\t\t NO WARRANTY", + "", + " 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO", + "WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.", + "EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR", + "OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY", + "KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE", + "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", + "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE", + "LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME", + "THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.", + "", + " 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN", + "WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY", + "AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU", + "FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR", + "CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE", + "LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING", + "RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A", + "FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF", + "SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH", + "DAMAGES.", + "", + "\t\t END OF TERMS AND CONDITIONS", + "", + " How to Apply These Terms to Your New Libraries", + "", + " If you develop a new library, and you want it to be of the greatest", + "possible use to the public, we recommend making it free software that", + "everyone can redistribute and change. You can do so by permitting", + "redistribution under these terms (or, alternatively, under the terms of the", + "ordinary General Public License).", + "", + " To apply these terms, attach the following notices to the library. It is", + "safest to attach them to the start of each source file to most effectively", + "convey the exclusion of warranty; and each file should have at least the", + "\"copyright\" line and a pointer to where the full notice is found.", + "", + " ", + " Copyright (C) ", + "", + " This library is free software; you can redistribute it and/or", + " modify it under the terms of the GNU Lesser General Public", + " License as published by the Free Software Foundation; either", + " version 2.1 of the License, or (at your option) any later version.", + "", + " This library is distributed in the hope that it will be useful,", + " but WITHOUT ANY WARRANTY; without even the implied warranty of", + " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU", + " Lesser General Public License for more details.", + "", + " You should have received a copy of the GNU Lesser General Public", + " License along with this library; if not, write to the Free Software", + " Foundation, Inc.,", + "51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA", + "", + "Also add information on how to contact you by electronic and paper mail.", + "", + "You should also get your employer (if you work as a programmer) or your", + "school, if any, to sign a \"copyright disclaimer\" for the library, if", + "necessary. Here is a sample; alter the names:", + "", + " Yoyodyne, Inc., hereby disclaims all copyright interest in the", + " library `Frob' (a library for tweaking knobs) written by James Random Hacker.", + "", + " ,", + "1 April 1990", + " Ty Coon, President of Vice", + "", + "That's all there is to it!" + ] + }, + { + // Added here because the module `parse5` has a dependency to it. + // The module `parse5` is shipped via the `extension-editing` built-in extension. + // The module `parse5` does not want to remove it https://github.com/inikulin/parse5/issues/225 + "name": "@types/node", + "licenseDetail": [ + "This project is licensed under the MIT license.", + "Copyrights are respective of each contributor listed at the beginning of each definition file.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] + }, + { + // We override the license that gets discovered at + // https://github.com/Microsoft/TypeScript/blob/master/LICENSE.txt + // because it does not contain a Copyright statement + "name": "typescript", + "licenseDetail": [ + "Copyright (c) Microsoft Corporation. All rights reserved.", + "", + "Apache License", + "", + "Version 2.0, January 2004", + "", + "http://www.apache.org/licenses/", + "", + "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", + "", + "1. Definitions.", + "", + "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", + "", + "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", + "", + "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", + "", + "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", + "", + "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", + "", + "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", + "", + "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", + "", + "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", + "", + "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", + "", + "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", + "", + "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", + "", + "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", + "", + "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", + "", + "You must give any other recipients of the Work or Derivative Works a copy of this License; and", + "", + "You must cause any modified files to carry prominent notices stating that You changed the files; and", + "", + "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", + "", + "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", + "", + "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", + "", + "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", + "", + "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", + "", + "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", + "", + "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", + "", + "END OF TERMS AND CONDITIONS" + ] + }, + { + // This module comes in from https://github.com/Microsoft/vscode-node-debug2/blob/master/package-lock.json + "name": "@types/source-map", + "licenseDetail": [ + "This project is licensed under the MIT license.", + "Copyrights are respective of each contributor listed at the beginning of each definition file.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] + }, + { + "name": "tunnel-agent", + "licenseDetail": [ + "Copyright (c) tunnel-agent authors", + "", + "Apache License", + "", + "Version 2.0, January 2004", + "", + "http://www.apache.org/licenses/", + "", + "TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION", + "", + "1. Definitions.", + "", + "\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.", + "", + "\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.", + "", + "\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.", + "", + "\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.", + "", + "\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.", + "", + "\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.", + "", + "\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).", + "", + "\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.", + "", + "\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"", + "", + "\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.", + "", + "2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.", + "", + "3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.", + "", + "4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:", + "", + "You must give any other recipients of the Work or Derivative Works a copy of this License; and", + "", + "You must cause any modified files to carry prominent notices stating that You changed the files; and", + "", + "You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and", + "", + "If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.", + "", + "5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.", + "", + "6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.", + "", + "7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.", + "", + "8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.", + "", + "9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.", + "", + "END OF TERMS AND CONDITIONS" + ] + }, + { + // Waiting for https://github.com/segmentio/noop-logger/issues/2 + "name": "noop-logger", + "licenseDetail": [ + "This project is licensed under the MIT license.", + "Copyrights are respective of each contributor listed at the beginning of each definition file.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + ] + }, + { + "name": "xterm-addon-search", + "licenseDetail": [ + "Copyright (c) 2017, The xterm.js authors (https://github.com/xtermjs/xterm.js)", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and associated documentation files (the \"Software\"), to deal", + "in the Software without restriction, including without limitation the rights", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", + "copies of the Software, and to permit persons to whom the Software is", + "furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN", + "THE SOFTWARE." + ] + }, + { + "name": "xterm-addon-web-links", + "licenseDetail": [ + "Copyright (c) 2017, The xterm.js authors (https://github.com/xtermjs/xterm.js)", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and associated documentation files (the \"Software\"), to deal", + "in the Software without restriction, including without limitation the rights", + "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", + "copies of the Software, and to permit persons to whom the Software is", + "furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Software.", + "", + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", + "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN", + "THE SOFTWARE." + ] + } +] From 3e52e92085c52cc508e33d505200a6074f63b846 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 14:44:42 +0200 Subject: [PATCH 271/364] oss 1.36.0 --- ThirdPartyNotices.txt | 199 +++++++++++++----------------------------- 1 file changed, 62 insertions(+), 137 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index df0fad7f82652..1d85443086427 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -5,107 +5,69 @@ Do Not Translate or Localize This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. -1. atom/language-c version 0.58.1 (https://github.com/atom/language-c) -2. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure) -3. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script) -4. atom/language-java version 0.31.2 (https://github.com/atom/language-java) -5. atom/language-objective-c version 0.15.0 (https://github.com/atom/language-objective-c) -6. atom/language-sass version 0.61.4 (https://github.com/atom/language-sass) -7. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript) -8. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml) -9. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes) -10. daaain/Handlebars version 1.8.0 (https://github.com/daaain/Handlebars) -11. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle) -12. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped) -13. demyte/language-cshtml version 0.3.0 (https://github.com/demyte/language-cshtml) -14. Document Object Model version 4.0.0 (https://www.w3.org/DOM/) -15. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage) -16. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation) -17. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle) -18. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift) -19. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/) -20. Ikuyadeu/vscode-R version 0.5.5 (https://github.com/Ikuyadeu/vscode-R) -21. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) -22. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) -23. jeff-hykin/cpp-textmate-grammar version 1.8.15 (https://github.com/jeff-hykin/cpp-textmate-grammar) -24. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) -25. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) -26. language-docker (https://github.com/moby/moby) -27. language-go version 0.44.3 (https://github.com/atom/language-go) -28. language-less version 0.34.2 (https://github.com/atom/language-less) -29. language-php version 0.44.1 (https://github.com/atom/language-php) -30. language-rust version 0.4.12 (https://github.com/zargony/atom-language-rust) -31. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) -32. marked version 0.6.2 (https://github.com/markedjs/marked) -33. mdn-data version 1.1.12 (https://github.com/mdn/data) -34. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage) -35. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage) -36. Microsoft/vscode-mssql version 1.4.0 (https://github.com/Microsoft/vscode-mssql) -37. mmims/language-batchfile version 0.7.5 (https://github.com/mmims/language-batchfile) -38. octicons version 8.3.0 (https://github.com/primer/octicons) -39. octref/language-css version 0.42.11 (https://github.com/octref/language-css) -40. PowerShell/EditorSyntax (https://github.com/powershell/editorsyntax) -41. promise-polyfill version 8.0.0 (https://github.com/taylorhakes/promise-polyfill) -42. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui) -43. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage) -44. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle) -45. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle) -46. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle) -47. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle) -48. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle) -49. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle) -50. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle) -51. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle) -52. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle) -53. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle) -54. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle) -55. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle) -56. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle) -57. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage) -58. TypeScript-TmLanguage version 1.0.0 (https://github.com/Microsoft/TypeScript-TmLanguage) -59. Unicode version 12.0.0 (http://www.unicode.org/) -60. vscode-logfile-highlighter version 2.4.1 (https://github.com/emilast/vscode-logfile-highlighter) -61. vscode-octicons-font version 1.3.0 (https://github.com/Microsoft/vscode-octicons-font) -62. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) -63. Web Background Synchronization (https://github.com/WICG/BackgroundSync) - - -%% atom/language-c NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) +1. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure) +2. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script) +3. atom/language-java version 0.31.2 (https://github.com/atom/language-java) +4. atom/language-sass version 0.61.4 (https://github.com/atom/language-sass) +5. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript) +6. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml) +7. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes) +8. daaain/Handlebars version 1.8.0 (https://github.com/daaain/Handlebars) +9. davidrios/pug-tmbundle (https://github.com/davidrios/pug-tmbundle) +10. definitelytyped (https://github.com/DefinitelyTyped/DefinitelyTyped) +11. demyte/language-cshtml version 0.3.0 (https://github.com/demyte/language-cshtml) +12. Document Object Model version 4.0.0 (https://www.w3.org/DOM/) +13. dotnet/csharp-tmLanguage version 0.1.0 (https://github.com/dotnet/csharp-tmLanguage) +14. expand-abbreviation version 0.5.8 (https://github.com/emmetio/expand-abbreviation) +15. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle) +16. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift) +17. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/) +18. Ikuyadeu/vscode-R version 0.5.5 (https://github.com/Ikuyadeu/vscode-R) +19. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) +20. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) +21. jeff-hykin/cpp-textmate-grammar version 1.11.0 (https://github.com/jeff-hykin/cpp-textmate-grammar) +22. jeff-hykin/cpp-textmate-grammar version 1.11.7 (https://github.com/jeff-hykin/cpp-textmate-grammar) +23. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) +24. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) +25. language-docker (https://github.com/moby/moby) +26. language-go version 0.44.3 (https://github.com/atom/language-go) +27. language-less version 0.34.2 (https://github.com/atom/language-less) +28. language-php version 0.44.1 (https://github.com/atom/language-php) +29. language-rust version 0.4.12 (https://github.com/zargony/atom-language-rust) +30. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) +31. marked version 0.6.2 (https://github.com/markedjs/marked) +32. mdn-data version 1.1.12 (https://github.com/mdn/data) +33. Microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/Microsoft/TypeScript-TmLanguage) +34. Microsoft/vscode-JSON.tmLanguage (https://github.com/Microsoft/vscode-JSON.tmLanguage) +35. Microsoft/vscode-mssql version 1.4.0 (https://github.com/Microsoft/vscode-mssql) +36. mmims/language-batchfile version 0.7.5 (https://github.com/mmims/language-batchfile) +37. octicons version 8.3.0 (https://github.com/primer/octicons) +38. octref/language-css version 0.42.11 (https://github.com/octref/language-css) +39. PowerShell/EditorSyntax (https://github.com/powershell/editorsyntax) +40. promise-polyfill version 8.0.0 (https://github.com/taylorhakes/promise-polyfill) +41. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui) +42. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage) +43. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle) +44. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle) +45. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle) +46. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle) +47. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle) +48. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle) +49. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle) +50. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle) +51. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle) +52. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle) +53. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle) +54. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle) +55. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle) +56. TypeScript-TmLanguage version 0.1.8 (https://github.com/Microsoft/TypeScript-TmLanguage) +57. TypeScript-TmLanguage version 1.0.0 (https://github.com/Microsoft/TypeScript-TmLanguage) +58. Unicode version 12.0.0 (http://www.unicode.org/) +59. vscode-logfile-highlighter version 2.4.1 (https://github.com/emilast/vscode-logfile-highlighter) +60. vscode-octicons-font version 1.3.1 (https://github.com/Microsoft/vscode-octicons-font) +61. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) +62. Web Background Synchronization (https://github.com/WICG/BackgroundSync) -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/textmate/c.tmbundle and distributed under the following -license, located in `README.mdown`: - -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. -========================================= -END OF atom/language-c NOTICES AND INFORMATION %% atom/language-clojure NOTICES AND INFORMATION BEGIN HERE ========================================= @@ -251,43 +213,6 @@ suitability for any purpose. ========================================= END OF atom/language-java NOTICES AND INFORMATION -%% atom/language-objective-c NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/textmate/objective-c.tmbundle and distributed under the following -license, located in `README.mdown`: - -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. -========================================= -END OF atom/language-objective-c NOTICES AND INFORMATION - %% atom/language-sass NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) From 8e791727268ab0cda8f4ac689b0be4b4954a806f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 14:48:43 +0200 Subject: [PATCH 272/364] workaround for #75830 --- src/vs/code/electron-main/window.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index ec398df67eddc..9c6813de1becf 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -156,7 +156,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { } } - if (isMacintosh && windowConfig && windowConfig.nativeTabs === true) { + const useNativeTabs = isMacintosh && windowConfig && windowConfig.nativeTabs === true; + if (useNativeTabs) { options.tabbingIdentifier = product.nameShort; // this opts in to sierra tabs } @@ -180,7 +181,10 @@ export class CodeWindow extends Disposable implements ICodeWindow { // TODO@Ben (Electron 4 regression): when running on multiple displays where the target display // to open the window has a larger resolution than the primary display, the window will not size // correctly unless we set the bounds again (https://github.com/microsoft/vscode/issues/74872) - if (isMacintosh && hasMultipleDisplays) { + // However, when running with native tabs we cannot use this workaround because there is a potential + // that the new window will be added as native tab instead of being a window on its own. In that + // case calling setBounds() would cause https://github.com/microsoft/vscode/issues/75830 + if (isMacintosh && hasMultipleDisplays && !useNativeTabs) { if ([this.windowState.width, this.windowState.height, this.windowState.x, this.windowState.y].every(value => typeof value === 'number')) { this._win.setBounds({ width: this.windowState.width!, From 2375b1f21de5c7af9f95ea44646e265fb203f09f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 14:51:19 +0200 Subject: [PATCH 273/364] update distro commit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8047f1c9e6a1..0f4051616eaf2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "e2de7806e752fbcf8be2bf6d3b0476cc49937ff0", + "distro": "05595573cc7515041a708d6ba0596dfeef29c250", "author": { "name": "Microsoft Corporation" }, From 6178c670e055b033f6384af33c8ce6ca2e01fb1f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 14:55:43 +0200 Subject: [PATCH 274/364] electron - still call setBounds() as workaround for first window --- src/vs/code/electron-main/window.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 9c6813de1becf..83e0aad634e67 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -181,10 +181,11 @@ export class CodeWindow extends Disposable implements ICodeWindow { // TODO@Ben (Electron 4 regression): when running on multiple displays where the target display // to open the window has a larger resolution than the primary display, the window will not size // correctly unless we set the bounds again (https://github.com/microsoft/vscode/issues/74872) - // However, when running with native tabs we cannot use this workaround because there is a potential - // that the new window will be added as native tab instead of being a window on its own. In that - // case calling setBounds() would cause https://github.com/microsoft/vscode/issues/75830 - if (isMacintosh && hasMultipleDisplays && !useNativeTabs) { + // + // However, when running with native tabs with multiple windows we cannot use this workaround + // because there is a potential that the new window will be added as native tab instead of being + // a window on its own. In that case calling setBounds() would cause https://github.com/microsoft/vscode/issues/75830 + if (isMacintosh && hasMultipleDisplays && (!useNativeTabs || BrowserWindow.getAllWindows().length === 1)) { if ([this.windowState.width, this.windowState.height, this.windowState.x, this.windowState.y].every(value => typeof value === 'number')) { this._win.setBounds({ width: this.windowState.width!, From 7b1a326985e9f58cafbfaa84b6d20a5be67c4100 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 24 Jun 2019 15:04:32 +0200 Subject: [PATCH 275/364] fixes #75753 --- extensions/git/src/repository.ts | 64 ++++++++++++++++++++++++++------ extensions/git/src/util.ts | 22 +++++++++-- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 5cbe55e8a2192..6018648f468dc 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,7 +5,7 @@ import { commands, Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, SourceControlInputBoxValidation, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento, SourceControlInputBoxValidationType, OutputChannel, LogLevel, env } from 'vscode'; import { Repository as BaseRepository, Commit, Stash, GitError, Submodule, CommitOptions, ForcePushMode } from './git'; -import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, toDisposable, combinedDisposable } from './util'; +import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent, combinedDisposable, watch, IFileWatcher } from './util'; import { memoize, throttle, debounce } from './decorators'; import { toGitUri } from './uri'; import { AutoFetcher } from './autofetch'; @@ -480,6 +480,49 @@ class FileEventLogger { } } +class DotGitWatcher implements IFileWatcher { + + readonly event: Event; + + private emitter = new EventEmitter(); + private transientDisposables: IDisposable[] = []; + private disposables: IDisposable[] = []; + + constructor(private repository: Repository) { + const rootWatcher = watch(repository.dotGit); + this.disposables.push(rootWatcher); + + const filteredRootWatcher = filterEvent(rootWatcher.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)); + this.event = anyEvent(filteredRootWatcher, this.emitter.event); + + repository.onDidRunGitStatus(this.updateTransientWatchers, this, this.disposables); + this.updateTransientWatchers(); + } + + private updateTransientWatchers() { + this.transientDisposables = dispose(this.transientDisposables); + + if (!this.repository.HEAD || !this.repository.HEAD.upstream) { + return; + } + + this.transientDisposables = dispose(this.transientDisposables); + + const { name, remote } = this.repository.HEAD.upstream; + const upstreamPath = path.join(this.repository.dotGit, 'refs', 'remotes', remote, name); + + const upstreamWatcher = watch(upstreamPath); + this.transientDisposables.push(upstreamWatcher); + upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables); + } + + dispose() { + this.emitter.dispose(); + this.transientDisposables = dispose(this.transientDisposables); + this.disposables = dispose(this.disposables); + } +} + export class Repository implements Disposable { private _onDidChangeRepository = new EventEmitter(); @@ -577,11 +620,14 @@ export class Repository implements Disposable { return this.repository.root; } + get dotGit(): string { + return this.repository.dotGit; + } + private isRepositoryHuge = false; private didWarnAboutLimit = false; private isFreshRepository: boolean | undefined = undefined; - private disposables: Disposable[] = []; constructor( @@ -596,23 +642,19 @@ export class Repository implements Disposable { const onWorkspaceRepositoryFileChange = filterEvent(onWorkspaceFileChange, uri => isDescendant(repository.root, uri.fsPath)); const onWorkspaceWorkingTreeFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => !/\/\.git($|\/)/.test(uri.path)); - const dotGitWatcher = fs.watch(repository.dotGit); - const onDotGitFileChangeEmitter = new EventEmitter(); - dotGitWatcher.on('change', (_, e) => onDotGitFileChangeEmitter.fire(Uri.file(path.join(repository.dotGit, e as string)))); - dotGitWatcher.on('error', err => console.error(err)); - this.disposables.push(toDisposable(() => dotGitWatcher.close())); - const onDotGitFileChange = filterEvent(onDotGitFileChangeEmitter.event, uri => !/\/\.git(\/index\.lock)?$/.test(uri.path)); + const dotGitFileWatcher = new DotGitWatcher(this); + this.disposables.push(dotGitFileWatcher); // FS changes should trigger `git status`: // - any change inside the repository working tree // - any change whithin the first level of the `.git` folder, except the folder itself and `index.lock` - const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, onDotGitFileChange); + const onFileChange = anyEvent(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event); onFileChange(this.onFileChange, this, this.disposables); // Relevate repository changes should trigger virtual document change events - onDotGitFileChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); + dotGitFileWatcher.event(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); - this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, onDotGitFileChange, outputChannel)); + this.disposables.push(new FileEventLogger(onWorkspaceWorkingTreeFileChange, dotGitFileWatcher.event, outputChannel)); const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index 7bf81adccd90c..c4e938506196a 100644 --- a/extensions/git/src/util.ts +++ b/extensions/git/src/util.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event } from 'vscode'; -import { dirname, sep } from 'path'; +import { Event, EventEmitter, Uri } from 'vscode'; +import { dirname, sep, join } from 'path'; import { Readable } from 'stream'; import * as fs from 'fs'; import * as byline from 'byline'; @@ -343,4 +343,20 @@ export function pathEquals(a: string, b: string): boolean { } return a === b; -} \ No newline at end of file +} + +export interface IFileWatcher extends IDisposable { + readonly event: Event; +} + +export function watch(location: string): IFileWatcher { + const dotGitWatcher = fs.watch(location); + const onDotGitFileChangeEmitter = new EventEmitter(); + dotGitWatcher.on('change', (_, e) => onDotGitFileChangeEmitter.fire(Uri.file(join(location, e as string)))); + dotGitWatcher.on('error', err => console.error(err)); + + return new class implements IFileWatcher { + event = onDotGitFileChangeEmitter.event; + dispose() { dotGitWatcher.close(); } + }; +} From b29d860226c259392066bd471de9bedbdb7a0838 Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Mon, 24 Jun 2019 15:26:34 +0200 Subject: [PATCH 276/364] node-debug@1.35.3 --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index ed6d6c2662d6a..7f1c9fd2f6fa5 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -1,7 +1,7 @@ [ { "name": "ms-vscode.node-debug", - "version": "1.35.2", + "version": "1.35.3", "repo": "https://github.com/Microsoft/vscode-node-debug", "metadata": { "id": "b6ded8fb-a0a0-4c1c-acbd-ab2a3bc995a6", From 6b781c7c26c895290a30f31c4d917ce854ef2d2c Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 24 Jun 2019 15:32:42 +0200 Subject: [PATCH 277/364] remove user data service --- src/vs/workbench/browser/web.main.ts | 12 +-- src/vs/workbench/electron-browser/main.ts | 12 +-- .../configuration/browser/configuration.ts | 55 ++--------- .../browser/configurationService.ts | 8 +- .../configurationEditingService.test.ts | 4 +- .../configurationService.test.ts | 35 +++---- .../userData/common/fileUserDataService.ts | 93 ------------------- .../userData/common/userDataService.ts | 32 ------- 8 files changed, 33 insertions(+), 218 deletions(-) delete mode 100644 src/vs/workbench/services/userData/common/fileUserDataService.ts delete mode 100644 src/vs/workbench/services/userData/common/userDataService.ts diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 9b4051ac41087..1986fb66422c9 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -35,8 +35,6 @@ import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; import { ProductService } from 'vs/platform/product/browser/productService'; -import { FileUserDataService } from '../services/userData/common/fileUserDataService'; -import { IUserDataService } from '../services/userData/common/userDataService'; class CodeRendererMain extends Disposable { @@ -119,14 +117,10 @@ class CodeRendererMain extends Disposable { fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); } - // User Data Service - const userDataService = this._register(new FileUserDataService(environmentService, fileService)); - serviceCollection.set(IUserDataService, userDataService); - const payload = await this.resolveWorkspaceInitializationPayload(); await Promise.all([ - this.createWorkspaceService(payload, environmentService, fileService, userDataService, remoteAgentService, logService).then(service => { + this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { // Workspace serviceCollection.set(IWorkspaceContextService, service); @@ -141,8 +135,8 @@ class CodeRendererMain extends Disposable { return { serviceCollection, logService }; } - private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, userDataService: IUserDataService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const workspaceService = new WorkspaceService({ remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, fileService, userDataService, remoteAgentService); + private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache() }, fileService, remoteAgentService); try { await workspaceService.initialize(payload); diff --git a/src/vs/workbench/electron-browser/main.ts b/src/vs/workbench/electron-browser/main.ts index 2d11615deb99e..87259d771c9da 100644 --- a/src/vs/workbench/electron-browser/main.ts +++ b/src/vs/workbench/electron-browser/main.ts @@ -50,8 +50,6 @@ import { ConfigurationCache } from 'vs/workbench/services/configuration/node/con import { SpdLogService } from 'vs/platform/log/node/spdlogService'; import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; -import { IUserDataService } from '../services/userData/common/userDataService'; -import { FileUserDataService } from '../services/userData/common/fileUserDataService'; class CodeRendererMain extends Disposable { @@ -207,14 +205,10 @@ class CodeRendererMain extends Disposable { fileService.registerProvider(Schemas.vscodeRemote, remoteFileSystemProvider); } - // User Data Service - const userDataService = this._register(new FileUserDataService(environmentService, fileService)); - serviceCollection.set(IUserDataService, userDataService); - const payload = await this.resolveWorkspaceInitializationPayload(environmentService); const services = await Promise.all([ - this.createWorkspaceService(payload, environmentService, fileService, userDataService, remoteAgentService, logService).then(service => { + this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { // Workspace serviceCollection.set(IWorkspaceContextService, service); @@ -310,8 +304,8 @@ class CodeRendererMain extends Disposable { return; } - private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, userDataService: IUserDataService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { - const workspaceService = new WorkspaceService({ remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + private async createWorkspaceService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: FileService, remoteAgentService: IRemoteAgentService, logService: ILogService): Promise { + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, remoteAuthority: this.configuration.remoteAuthority, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); try { await workspaceService.initialize(payload); diff --git a/src/vs/workbench/services/configuration/browser/configuration.ts b/src/vs/workbench/services/configuration/browser/configuration.ts index 14bade5275628..a2f7603280985 100644 --- a/src/vs/workbench/services/configuration/browser/configuration.ts +++ b/src/vs/workbench/services/configuration/browser/configuration.ts @@ -12,7 +12,7 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels'; import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels'; -import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, USER_CONFIGURATION_KEY, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration'; import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; @@ -23,51 +23,12 @@ import { Schemas } from 'vs/base/common/network'; import { IConfigurationModel } from 'vs/platform/configuration/common/configuration'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { hash } from 'vs/base/common/hash'; -import { IUserDataService } from '../../userData/common/userDataService'; - -export class UserConfiguration extends Disposable { - - private readonly parser: ConfigurationModelParser; - private readonly reloadConfigurationScheduler: RunOnceScheduler; - protected readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); - readonly onDidChangeConfiguration: Event = this._onDidChangeConfiguration.event; - - constructor( - private readonly scopes: ConfigurationScope[] | undefined, - private readonly userDataService: IUserDataService - ) { - super(); - - this.parser = new ConfigurationModelParser(USER_CONFIGURATION_KEY, this.scopes); - this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50)); - this._register(Event.filter(this.userDataService.onDidChange, e => e.contains(USER_CONFIGURATION_KEY))(() => this.reloadConfigurationScheduler.schedule())); - } - - async initialize(): Promise { - return this.reload(); - } - - async reload(): Promise { - try { - const content = (await this.userDataService.read(USER_CONFIGURATION_KEY)) || '{}'; - this.parser.parseContent(content); - return this.parser.configurationModel; - } catch (e) { - return new ConfigurationModel(); - } - } - - reprocess(): ConfigurationModel { - this.parser.parse(); - return this.parser.configurationModel; - } -} export class RemoteUserConfiguration extends Disposable { - private readonly _cachedConfiguration: CachedRemoteUserConfiguration; + private readonly _cachedConfiguration: CachedUserConfiguration; private readonly _configurationFileService: ConfigurationFileService; - private _userConfiguration: FileServiceBasedRemoteUserConfiguration | CachedRemoteUserConfiguration; + private _userConfiguration: UserConfiguration | CachedUserConfiguration; private _userConfigurationInitializationPromise: Promise | null = null; private readonly _onDidChangeConfiguration: Emitter = this._register(new Emitter()); @@ -81,10 +42,10 @@ export class RemoteUserConfiguration extends Disposable { ) { super(); this._configurationFileService = configurationFileService; - this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache); + this._userConfiguration = this._cachedConfiguration = new CachedUserConfiguration(remoteAuthority, configurationCache); remoteAgentService.getEnvironment().then(async environment => { if (environment) { - const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService)); + const userConfiguration = this._register(new UserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService)); this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel))); this._userConfigurationInitializationPromise = userConfiguration.initialize(); const configurationModel = await this._userConfigurationInitializationPromise; @@ -96,7 +57,7 @@ export class RemoteUserConfiguration extends Disposable { } async initialize(): Promise { - if (this._userConfiguration instanceof FileServiceBasedRemoteUserConfiguration) { + if (this._userConfiguration instanceof UserConfiguration) { return this._userConfiguration.initialize(); } @@ -129,7 +90,7 @@ export class RemoteUserConfiguration extends Disposable { } } -class FileServiceBasedRemoteUserConfiguration extends Disposable { +export class UserConfiguration extends Disposable { private readonly parser: ConfigurationModelParser; private readonly reloadConfigurationScheduler: RunOnceScheduler; @@ -229,7 +190,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable { } } -class CachedRemoteUserConfiguration extends Disposable { +class CachedUserConfiguration extends Disposable { private readonly _onDidChange: Emitter = this._register(new Emitter()); readonly onDidChange: Event = this._onDidChange.event; diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index bf934755350ea..0152a86f84ae6 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -29,7 +29,6 @@ import { isEqual, dirname } from 'vs/base/common/resources'; import { mark } from 'vs/base/common/performance'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IFileService } from 'vs/platform/files/common/files'; -import { IUserDataService } from 'vs/workbench/services/userData/common/userDataService'; export class WorkspaceService extends Disposable implements IConfigurationService, IWorkspaceContextService { @@ -68,10 +67,9 @@ export class WorkspaceService extends Disposable implements IConfigurationServic private cyclicDependency = new Promise(resolve => this.cyclicDependencyReady = resolve); constructor( - { remoteAuthority, configurationCache }: { remoteAuthority?: string, configurationCache: IConfigurationCache }, + { userSettingsResource, remoteAuthority, configurationCache }: { userSettingsResource: URI, remoteAuthority?: string, configurationCache: IConfigurationCache }, fileService: IFileService, - userDataService: IUserDataService, - remoteAgentService: IRemoteAgentService + remoteAgentService: IRemoteAgentService, ) { super(); @@ -81,7 +79,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic this.configurationFileService = new ConfigurationFileService(fileService); this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap(), this.workspace); this.cachedFolderConfigs = new ResourceMap(); - this.localUserConfiguration = this._register(new UserConfiguration(remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, userDataService)); + this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, this.configurationFileService)); this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration))); if (remoteAuthority) { this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService)); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts index f94f09794b480..64b5b994371ad 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts @@ -39,7 +39,6 @@ import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFileSystemProvider'; import { IFileService } from 'vs/platform/files/common/files'; import { ConfigurationCache } from 'vs/workbench/services/configuration/node/configurationCache'; -import { FileUserDataService } from 'vs/workbench/services/userData/common/fileUserDataService'; class SettingsTestEnvironmentService extends EnvironmentService { @@ -108,8 +107,7 @@ suite('ConfigurationEditingService', () => { fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); instantiationService.stub(IFileService, fileService); instantiationService.stub(IRemoteAgentService, remoteAgentService); - const userDataService = new FileUserDataService(environmentService, fileService); - const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); return workspaceService.initialize(noWorkspace ? { id: '' } : { folder: URI.file(workspaceDir), id: createHash('md5').update(URI.file(workspaceDir).toString()).digest('hex') }).then(() => { instantiationService.stub(IConfigurationService, workspaceService); diff --git a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts index 3e1e4be3e3c7e..cbd400263ee98 100644 --- a/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts @@ -31,7 +31,7 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/ import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService'; import { createHash } from 'crypto'; import { Schemas } from 'vs/base/common/network'; -import { originalFSPath, dirname } from 'vs/base/common/resources'; +import { originalFSPath } from 'vs/base/common/resources'; import { isLinux } from 'vs/base/common/platform'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; @@ -45,16 +45,14 @@ import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEn import { IConfigurationCache } from 'vs/workbench/services/configuration/common/configuration'; import { VSBuffer } from 'vs/base/common/buffer'; import { SignService } from 'vs/platform/sign/browser/signService'; -import { FileUserDataService } from 'vs/workbench/services/userData/common/fileUserDataService'; class SettingsTestEnvironmentService extends EnvironmentService { - constructor(args: ParsedArgs, _execPath: string, private _settingsPath: string) { + constructor(args: ParsedArgs, _execPath: string, private customAppSettingsHome: string) { super(args, _execPath); } - get appSettingsHome(): URI { return dirname(this.settingsResource); } - get settingsResource(): URI { return URI.file(this._settingsPath); } + get settingsResource(): URI { return URI.file(this.customAppSettingsHome); } } function setUpFolderWorkspace(folderName: string): Promise<{ parentDir: string, folderDir: string }> { @@ -105,9 +103,7 @@ suite('WorkspaceContextService - Folder', () => { workspaceResource = folderDir; const globalSettingsFile = path.join(parentDir, 'settings.json'); const environmentService = new SettingsTestEnvironmentService(parseArgs(process.argv), process.execPath, globalSettingsFile); - const fileService = new FileService(new NullLogService()); - const userDataService = new FileUserDataService(environmentService, fileService); - workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); + workspaceContextService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, new FileService(new NullLogService()), new RemoteAgentService({}, environmentService, new RemoteAuthorityResolverService(), new SignService())); return (workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir))); }); }); @@ -171,8 +167,7 @@ suite('WorkspaceContextService - Workspace', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const userDataService = new FileUserDataService(environmentService, fileService); - const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, fileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -230,8 +225,8 @@ suite('WorkspaceContextService - Workspace Editing', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const userDataService = new FileUserDataService(environmentService, fileService); - const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + const configurationFileService = fileService; + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -490,8 +485,8 @@ suite('WorkspaceService - Initialization', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const userDataService = new FileUserDataService(environmentService, fileService); - const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + const configurationFileService = fileService; + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -753,8 +748,8 @@ suite('WorkspaceConfigurationService - Folder', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const userDataService = new FileUserDataService(environmentService, fileService); - const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + const configurationFileService = fileService; + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); instantiationService.stub(IEnvironmentService, environmentService); @@ -1080,8 +1075,8 @@ suite('WorkspaceConfigurationService-Multiroot', () => { instantiationService.stub(IRemoteAgentService, remoteAgentService); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, new DiskFileSystemProvider(new NullLogService())); - const userDataService = new FileUserDataService(environmentService, fileService); - const workspaceService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, fileService, userDataService, remoteAgentService); + const configurationFileService = fileService; + const workspaceService = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache: new ConfigurationCache(environmentService) }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, workspaceService); instantiationService.stub(IConfigurationService, workspaceService); @@ -1481,9 +1476,9 @@ suite('WorkspaceConfigurationService - Remote Folder', () => { const remoteAgentService = instantiationService.stub(IRemoteAgentService, >{ getEnvironment: () => remoteEnvironmentPromise }); const fileService = new FileService(new NullLogService()); fileService.registerProvider(Schemas.file, diskFileSystemProvider); + const configurationFileService = fileService; const configurationCache: IConfigurationCache = { read: () => Promise.resolve(''), write: () => Promise.resolve(), remove: () => Promise.resolve() }; - const userDataService = new FileUserDataService(environmentService, fileService); - testObject = new WorkspaceService({ configurationCache, remoteAuthority }, fileService, userDataService, remoteAgentService); + testObject = new WorkspaceService({ userSettingsResource: environmentService.settingsResource, configurationCache, remoteAuthority }, configurationFileService, remoteAgentService); instantiationService.stub(IWorkspaceContextService, testObject); instantiationService.stub(IConfigurationService, testObject); instantiationService.stub(IEnvironmentService, environmentService); diff --git a/src/vs/workbench/services/userData/common/fileUserDataService.ts b/src/vs/workbench/services/userData/common/fileUserDataService.ts deleted file mode 100644 index 6096274dc6dee..0000000000000 --- a/src/vs/workbench/services/userData/common/fileUserDataService.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Event, Emitter } from 'vs/base/common/event'; -import { Disposable } from 'vs/base/common/lifecycle'; -import { IUserDataService, IUserDataChangesEvent } from './userDataService'; -import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files'; -import { URI } from 'vs/base/common/uri'; -import * as resources from 'vs/base/common/resources'; -import { TernarySearchTree } from 'vs/base/common/map'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; - -export class FileUserDataService extends Disposable implements IUserDataService { - _serviceBrand: any; - - private readonly settingsHome: URI; - - private _onDidChange: Emitter = this._register(new Emitter()); - readonly onDidChange: Event = this._onDidChange.event; - - constructor( - @IEnvironmentService environmentService: IEnvironmentService, - @IFileService private readonly fileService: IFileService - ) { - super(); - // Assumption: This path always exists - this.settingsHome = environmentService.appSettingsHome; - this.fileService.watch(this.settingsHome); - - this._register(this.fileService.onFileChanges(e => this.handleFileChanges(e))); - } - - private handleFileChanges(event: FileChangesEvent): void { - const changedKeys: string[] = []; - for (const change of event.changes) { - const key = resources.relativePath(this.settingsHome, change.resource); - if (key) { - changedKeys.push(key); - } - } - if (changedKeys.length) { - this._onDidChange.fire(new UserDataChangesEvent(changedKeys)); - } - } - - async read(key: string): Promise { - const resource = this.toResource(key); - try { - const content = await this.fileService.readFile(resource); - return content.value.toString(); - } catch (e) { - const exists = await this.fileService.exists(resource); - if (exists) { - throw e; - } - } - return ''; - } - - write(key: string, value: string): Promise { - return this.fileService.writeFile(this.toResource(key), VSBuffer.fromString(value)).then(() => undefined); - } - - private toResource(key: string): URI { - return resources.joinPath(this.settingsHome, ...key.split('/')); - } - -} - -class UserDataChangesEvent implements IUserDataChangesEvent { - - private _keysTree: TernarySearchTree | undefined = undefined; - - constructor(readonly keys: string[]) { } - - private get keysTree(): TernarySearchTree { - if (!this._keysTree) { - this._keysTree = TernarySearchTree.forPaths(); - for (const key of this.keys) { - this._keysTree.set(key, key); - } - } - return this._keysTree; - } - - contains(keyOrSegment: string): boolean { - return this.keysTree.findSubstr(keyOrSegment) !== undefined; - } - -} \ No newline at end of file diff --git a/src/vs/workbench/services/userData/common/userDataService.ts b/src/vs/workbench/services/userData/common/userDataService.ts deleted file mode 100644 index 81c8b5dfd76db..0000000000000 --- a/src/vs/workbench/services/userData/common/userDataService.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { Event } from 'vs/base/common/event'; - -export const IUserDataService = createDecorator('userDataService'); - -export interface IUserDataChangesEvent { - keys: string[]; - contains(keyOrSegment: string): boolean; -} - -export interface IUserDataService { - _serviceBrand: any; - - onDidChange: Event; - - read(key: string): Promise; - - write(key: string, value: string): Promise; -} - -export const IUserDataEditorService = createDecorator('userDataEditorService'); - -export interface IUserDataEditorService { - _serviceBrand: any; - - openInEditor(key: string): Promise; -} \ No newline at end of file From b4aabbf31f30239ea1cc49e3c146f050fafa4994 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 15:40:19 +0200 Subject: [PATCH 278/364] use posix.join --- .../src/singlefolder-tests/workspace.fs.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts index 92fe43e125f34..cd82f10c17d78 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; -import { join } from 'path'; +import { posix } from 'path'; suite('workspace-fs', () => { @@ -54,7 +54,7 @@ suite('workspace-fs', () => { test('fs.write/stat/delete', async function () { - const uri = root.with({ path: join(root.path, 'new.file') }); + const uri = root.with({ path: posix.join(root.path, 'new.file') }); await vscode.workspace.fs.writeFile(uri, Buffer.from('HELLO')); const stat = await vscode.workspace.fs.stat(uri); @@ -72,8 +72,8 @@ suite('workspace-fs', () => { test('fs.delete folder', async function () { - const folder = root.with({ path: join(root.path, 'folder') }); - const file = root.with({ path: join(root.path, 'folder/file') }); + const folder = root.with({ path: posix.join(root.path, 'folder') }); + const file = root.with({ path: posix.join(root.path, 'folder/file') }); await vscode.workspace.fs.createDirectory(folder); await vscode.workspace.fs.writeFile(file, Buffer.from('FOO')); From 071348aa2c3379c1a0e23f98ed9272ed7af3081b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 15:42:43 +0200 Subject: [PATCH 279/364] update doc --- src/vs/vscode.proposed.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 0e3c3c9b36e31..272d73f670927 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -65,7 +65,7 @@ declare module 'vscode' { * * *Note* that the value is `undefined` when there is no remote extension host but that the * value is defined in all extension hosts (local and remote) in case a remote extension host - * exists. Use [`ExtensionContext#extensionKind`](#ExtensionContext.extensionKind) to know if + * exists. Use [`Extension#extensionKind`](#Extension.extensionKind) to know if * a specific extension runs remote or not. */ export const remoteName: string | undefined; From a35956820b21f8b7c9d22b457fe0a1ee6c0f1d25 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 24 Jun 2019 15:49:56 +0200 Subject: [PATCH 280/364] Add -1 tab index to status bar entries This keeps them out of the tab order, but allows them to be read with a screen reader Fixes #41406 --- src/vs/workbench/browser/parts/statusbar/statusbarPart.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index dcc9d5da3de32..ab4e44c096d78 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -661,6 +661,7 @@ class StatusbarEntryItem extends Disposable { // Label Container this.labelContainer = document.createElement('a'); + this.labelContainer.tabIndex = -1; // allows screen readers to read title, but still prevents tab focus. // Label this.label = new OcticonLabel(this.labelContainer); @@ -718,7 +719,7 @@ class StatusbarEntryItem extends Disposable { this.applyColor(this.labelContainer, entry.color); } - // Update: Backgroud + // Update: Background if (!this.entry || entry.backgroundColor !== this.entry.backgroundColor) { if (entry.backgroundColor) { this.applyColor(this.container, entry.backgroundColor, true); From cbb1c724cdf5bcaa09602beb0eef978373deb7d2 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 24 Jun 2019 15:55:44 +0200 Subject: [PATCH 281/364] empty view polish labels for remote case microsoft/vscode-remote-release#511 --- .../contrib/files/browser/views/emptyView.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index dc40cbe11c262..cad0e825ff0e8 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -21,6 +21,9 @@ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/v import { ResourcesDropHandler, DragAndDropObserver } from 'vs/workbench/browser/dnd'; import { listDropBackground } from 'vs/platform/theme/common/colorRegistry'; import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { ILabelService } from 'vs/platform/label/common/label'; +import { Schemas } from 'vs/base/common/network'; export class EmptyView extends ViewletPanel { @@ -38,10 +41,13 @@ export class EmptyView extends ViewletPanel { @IKeybindingService keybindingService: IKeybindingService, @IContextMenuService contextMenuService: IContextMenuService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @IConfigurationService configurationService: IConfigurationService + @IConfigurationService configurationService: IConfigurationService, + @IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService, + @ILabelService private labelService: ILabelService ) { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: nls.localize('explorerSection', "Files Explorer Section") }, keybindingService, contextMenuService, configurationService); - this.contextService.onDidChangeWorkbenchState(() => this.setLabels()); + this._register(this.contextService.onDidChangeWorkbenchState(() => this.setLabels())); + this._register(this.labelService.onDidChangeFormatters(() => this.setLabels())); } renderHeader(container: HTMLElement): void { @@ -117,7 +123,12 @@ export class EmptyView extends ViewletPanel { } this.titleElement.textContent = EmptyView.NAME; } else { - this.messageElement.textContent = nls.localize('noFolderHelp', "You have not yet opened a folder."); + if (this.environmentService.configuration.remoteAuthority) { + const hostLabel = this.labelService.getHostLabel(Schemas.vscodeRemote, this.environmentService.configuration.remoteAuthority); + this.messageElement.textContent = hostLabel ? nls.localize('remoteNoFolderHelp', "Connected to {0}", hostLabel) : nls.localize('connecting', "Connecting..."); + } else { + this.messageElement.textContent = nls.localize('noFolderHelp', "You have not yet opened a folder."); + } if (this.button) { this.button.label = nls.localize('openFolder', "Open Folder"); } From f16c39cfc44884d4c3cc45191812b4a02cdc90b1 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 24 Jun 2019 16:12:10 +0200 Subject: [PATCH 282/364] send remote watcher error to file service (fixes microsoft/vscode-remote-release#329) --- src/vs/platform/files/common/files.ts | 2 +- .../remote/common/remoteAgentFileSystemChannel.ts | 13 +++++++++++-- .../workbench/services/files/common/fileService.ts | 2 +- .../services/files/node/diskFileSystemProvider.ts | 8 ++++---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index ac73dd3de191e..69b1fb785d488 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -208,7 +208,7 @@ export interface IFileSystemProvider { readonly capabilities: FileSystemProviderCapabilities; readonly onDidChangeCapabilities: Event; - readonly onDidErrorOccur?: Event; // TODO@ben remove once file watchers are solid + readonly onDidErrorOccur?: Event; // TODO@ben remove once file watchers are solid readonly onDidChangeFile: Event; watch(resource: URI, opts: IWatchOptions): IDisposable; diff --git a/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts b/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts index fdc022b18d9c6..edc89fb407e0c 100644 --- a/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts +++ b/src/vs/platform/remote/common/remoteAgentFileSystemChannel.ts @@ -27,6 +27,9 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF private readonly _onDidChange = this._register(new Emitter()); readonly onDidChangeFile: Event = this._onDidChange.event; + private _onDidWatchErrorOccur: Emitter = this._register(new Emitter()); + get onDidErrorOccur(): Event { return this._onDidWatchErrorOccur.event; } + private readonly _onDidChangeCapabilities = this._register(new Emitter()); readonly onDidChangeCapabilities: Event = this._onDidChangeCapabilities.event; @@ -43,8 +46,14 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF } private registerListeners(): void { - this._register(this.channel.listen('filechange', [this.session])((events) => { - this._onDidChange.fire(events.map(event => ({ resource: URI.revive(event.resource), type: event.type }))); + this._register(this.channel.listen('filechange', [this.session])((eventsOrError) => { + if (Array.isArray(eventsOrError)) { + const events = eventsOrError; + this._onDidChange.fire(events.map(event => ({ resource: URI.revive(event.resource), type: event.type }))); + } else { + const error = eventsOrError; + this._onDidWatchErrorOccur.fire(error); + } })); } diff --git a/src/vs/workbench/services/files/common/fileService.ts b/src/vs/workbench/services/files/common/fileService.ts index fd0a0d9f4e952..a788aadc1fd25 100644 --- a/src/vs/workbench/services/files/common/fileService.ts +++ b/src/vs/workbench/services/files/common/fileService.ts @@ -52,7 +52,7 @@ export class FileService extends Disposable implements IFileService { const providerDisposables = new DisposableStore(); providerDisposables.add(provider.onDidChangeFile(changes => this._onFileChanges.fire(new FileChangesEvent(changes)))); if (typeof provider.onDidErrorOccur === 'function') { - providerDisposables.add(provider.onDidErrorOccur(error => this._onError.fire(error))); + providerDisposables.add(provider.onDidErrorOccur(error => this._onError.fire(new Error(error)))); } return toDisposable(() => { diff --git a/src/vs/workbench/services/files/node/diskFileSystemProvider.ts b/src/vs/workbench/services/files/node/diskFileSystemProvider.ts index a645ac84ef03c..9cdf02e1438ef 100644 --- a/src/vs/workbench/services/files/node/diskFileSystemProvider.ts +++ b/src/vs/workbench/services/files/node/diskFileSystemProvider.ts @@ -338,8 +338,8 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro //#region File Watching - private _onDidWatchErrorOccur: Emitter = this._register(new Emitter()); - get onDidErrorOccur(): Event { return this._onDidWatchErrorOccur.event; } + private _onDidWatchErrorOccur: Emitter = this._register(new Emitter()); + get onDidErrorOccur(): Event { return this._onDidWatchErrorOccur.event; } private _onDidChangeFile: Emitter = this._register(new Emitter()); get onDidChangeFile(): Event { return this._onDidChangeFile.event; } @@ -441,7 +441,7 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro event => this._onDidChangeFile.fire(toFileChanges(event)), msg => { if (msg.type === 'error') { - this._onDidWatchErrorOccur.fire(new Error(msg.message)); + this._onDidWatchErrorOccur.fire(msg.message); } this.logService[msg.type](msg.message); }, @@ -466,7 +466,7 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro changes => this._onDidChangeFile.fire(toFileChanges(changes)), msg => { if (msg.type === 'error') { - this._onDidWatchErrorOccur.fire(new Error(msg.message)); + this._onDidWatchErrorOccur.fire(msg.message); } this.logService[msg.type](msg.message); }, From 59e50ff7993addab248a3775faa15dbaf4bb97f1 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 24 Jun 2019 16:19:57 +0200 Subject: [PATCH 283/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f4051616eaf2..bbd1ab905cef4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "05595573cc7515041a708d6ba0596dfeef29c250", + "distro": "d2c482aba7912623c65fa4da1ea722f32558197c", "author": { "name": "Microsoft Corporation" }, From 18dfdcbf52eddc54b23e7f4756d9db1e6d83a92c Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 24 Jun 2019 07:47:26 -0700 Subject: [PATCH 284/364] better error handling in case of loader error in tests --- test/electron/index.js | 7 +++++++ test/electron/renderer.js | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/test/electron/index.js b/test/electron/index.js index ebd97e3b98bf0..b0d82f6d1bdc8 100644 --- a/test/electron/index.js +++ b/test/electron/index.js @@ -100,6 +100,13 @@ function parseReporterOption(value) { app.on('ready', () => { + ipcMain.on('error', (_, err) => { + if (!argv.debug) { + console.error(err); + app.exit(1); + } + }); + const win = new BrowserWindow({ height: 600, width: 800, diff --git a/test/electron/renderer.js b/test/electron/renderer.js index addb1f0b93c45..bd8cba69214bd 100644 --- a/test/electron/renderer.js +++ b/test/electron/renderer.js @@ -273,5 +273,12 @@ function runTests(opts) { ipcRenderer.on('run', (e, opts) => { initLoader(opts); - runTests(opts).catch(err => console.error(typeof err === 'string' ? err : JSON.stringify(err))); + runTests(opts).catch(err => { + if (!(typeof err !== 'string')) { + err = JSON.stringify(err); + } + + console.error(err); + ipcRenderer.send('error', err); + }); }); From dbb361ebd0b9b176de4ac78114ef194ce941e54e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 24 Jun 2019 16:55:06 +0200 Subject: [PATCH 285/364] fix win 32 bits unit tests --- build/azure-pipelines/win32/product-build-win32.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 18758af4f997e..3fe19e4b847b0 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -22,8 +22,6 @@ steps: . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" "machine monacotools.visualstudio.com`npassword $(devops-pat)`nmachine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII - $env:npm_config_arch="$(VSCODE_ARCH)" - $env:CHILD_CONCURRENCY="1" exec { git config user.email "vscode@microsoft.com" } exec { git config user.name "VSCode" } @@ -40,6 +38,8 @@ steps: - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" + $env:npm_config_arch="$(VSCODE_ARCH)" + $env:CHILD_CONCURRENCY="1" exec { yarn } displayName: Install dependencies From 28a51a3f4506a18caa776c02a7a49747d3009b95 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 17:05:19 +0200 Subject: [PATCH 286/364] electron@4.2.5 (#76020) --- .yarnrc | 2 +- cgmanifest.json | 4 ++-- src/typings/electron.d.ts | 2 +- test/smoke/package.json | 2 +- test/smoke/yarn.lock | 8 ++++---- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.yarnrc b/.yarnrc index e3807c54e5142..441b5a2e69aac 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,3 +1,3 @@ disturl "https://atom.io/download/electron" -target "4.2.4" +target "4.2.5" runtime "electron" diff --git a/cgmanifest.json b/cgmanifest.json index 42a65648e593b..b8c4f3bfefc0e 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -60,12 +60,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "c1b5a1cfc8a14a337540193daecfa5d0f50dd7bb" + "commitHash": "5d67ec3da5376a5058990e8a9557bc9124ad59a8" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "4.2.4" + "version": "4.2.5" }, { "component": { diff --git a/src/typings/electron.d.ts b/src/typings/electron.d.ts index df64e7a0b2857..c52a879c36f39 100644 --- a/src/typings/electron.d.ts +++ b/src/typings/electron.d.ts @@ -1,4 +1,4 @@ -// Type definitions for Electron 4.2.4 +// Type definitions for Electron 4.2.5 // Project: http://electronjs.org/ // Definitions by: The Electron Team // Definitions: https://github.com/electron/electron-typescript-definitions diff --git a/test/smoke/package.json b/test/smoke/package.json index 2aff1bced09c4..80f93f04d89dd 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -22,7 +22,7 @@ "@types/webdriverio": "4.6.1", "concurrently": "^3.5.1", "cpx": "^1.5.0", - "electron": "4.2.4", + "electron": "4.2.5", "htmlparser2": "^3.9.2", "mkdirp": "^0.5.1", "mocha": "^5.2.0", diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index da2b5b77ed557..b6424c799b9d4 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -596,10 +596,10 @@ electron-download@^4.1.0: semver "^5.4.1" sumchecker "^2.0.2" -electron@4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.4.tgz#68ca7bd4ff2c16b9205549322f0f1cda4ebc9ff9" - integrity sha512-d4wEwJluMsRyRgbukLmFVTb6l1J+mc3RLB1ctbpMlSWDFvs+zknPWa+cHBzTWwrdgwINLddr69qsAW1ku6FqYw== +electron@4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/electron/-/electron-4.2.5.tgz#1d1432c38e2b2190318f7ca30897cdfdcf942e5a" + integrity sha512-P132MXzTtyn2ZaekhKi5JeHzmTAMuR/uQt4hrg3vfJV7fpncx9SL6UFwHAK1DU13iiyZJqqIziNUu+o8nODHsA== dependencies: "@types/node" "^10.12.18" electron-download "^4.1.0" From 99ebdaa7dc7592987aafa9ab88bd82633104a17e Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 24 Jun 2019 18:10:47 +0200 Subject: [PATCH 287/364] Code-insiders started from WSL doesn't return to console/ doesn't connect. Fixes microsoft/vscode-remote-release#780 --- resources/win32/bin/code.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/win32/bin/code.sh b/resources/win32/bin/code.sh index 28c48b8d72d2a..5d92383c496be 100644 --- a/resources/win32/bin/code.sh +++ b/resources/win32/bin/code.sh @@ -16,7 +16,7 @@ if grep -qi Microsoft /proc/version; then WSL_BUILD=18362 else WSL_BUILD=$(uname -r | sed -E 's/^.+-([0-9]+)-Microsoft/\1/') - if ! [ -z "$WSL_BUILD" ]; then + if [ -z "$WSL_BUILD" ]; then WSL_BUILD=0 fi fi From b86b7f1ba07b092d25ab2fbcbe1b8e2fd906871b Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 24 Jun 2019 09:19:07 -0700 Subject: [PATCH 288/364] Group decorations by line before rendering --- .../browser/viewParts/minimap/minimap.ts | 58 ++++++++++++------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index fa023adedd5ab..bb68a3af249cd 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -737,50 +737,64 @@ export class Minimap extends ViewPart { const lineHeightRatio = renderMinimap === RenderMinimap.LargeBlocks || renderMinimap === RenderMinimap.SmallBlocks ? 0.5 : 1; const height = lineHeight * lineHeightRatio; - for (let i = 0; i < decorations.length; i++) { - if (decorations[i].options.minimap) { - this.renderDecoration(canvasContext, decorations[i], layout, height, lineHeight, tabSize, characterWidth); + // Loop over decorations, ignoring those that don't have the minimap property set and rendering those on the same line together + let i = 0; + for (; i < decorations.length; i++) { + if (!decorations[i].options.minimap) { + continue; } + + let decorationsForLine = [decorations[i]]; + let currentLine = decorations[i].range.startLineNumber; + let j = i + 1; + while (j < decorations.length && decorations[j].range.startLineNumber === currentLine) { + if (decorations[j].options.minimap) { + decorationsForLine.push(decorations[j]); + } + + j += 1; + } + + i = j - 1; + this.renderDecorationsForLine(canvasContext, decorationsForLine, layout, currentLine, height, lineHeight, tabSize, characterWidth); } } } - private renderDecoration(canvasContext: CanvasRenderingContext2D, - decoration: ViewModelDecoration, + private renderDecorationsForLine(canvasContext: CanvasRenderingContext2D, + decorations: ViewModelDecoration[], layout: MinimapLayout, + startLineNumber: number, height: number, lineHeight: number, tabSize: number, charWidth: number) { - const { startLineNumber, startColumn, endColumn } = decoration.range; - - const startIndex = startColumn - 1; - const endIndex = endColumn - 1; - const y = (startLineNumber - layout.startLineNumber) * lineHeight; - // Get the offset of the decoration in the line. Have to read line data to see how much space each character takes. - let x = 0; - let endPosition = 0; const lineData = this._context.model.getLineContent(startLineNumber); - for (let i = 0; i < endIndex; i++) { - const charCode = lineData.charCodeAt(i); + const lineIndexToXOffset = [0]; + for (let i = 1; i < lineData.length + 1; i++) { + const charCode = lineData.charCodeAt(i - 1); const dx = charCode === CharCode.Tab ? tabSize * charWidth : strings.isFullWidthCharacter(charCode) ? 2 * charWidth : charWidth; - if (i < startIndex) { - x += dx; - } - - endPosition += dx; + lineIndexToXOffset[i] = lineIndexToXOffset[i - 1] + dx; } - const width = endPosition - x; + for (let i = 0; i < decorations.length; i++) { + const currentDecoration = decorations[i]; + const { startColumn, endColumn } = currentDecoration.range; + const x = lineIndexToXOffset[startColumn - 1]; + const width = lineIndexToXOffset[endColumn - 1] - x; + + this.renderADecoration(canvasContext, currentDecoration.options.minimap, x, y, width, height); + } + } - const minimapOptions = decoration.options.minimap; + private renderADecoration(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, x: number, y: number, width: number, height: number) { const decorationColor = minimapOptions.getColor(this._context.theme); canvasContext.fillStyle = decorationColor; From 4a15a87336c6450681f2b2b70bec1bf840d2b8d3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 18:21:47 +0200 Subject: [PATCH 289/364] disable support for simple fullscreen (#75054) --- src/vs/code/electron-main/window.ts | 17 +++++++++-------- src/vs/platform/windows/common/windows.ts | 2 +- .../electron-browser/main.contribution.ts | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 83e0aad634e67..885ecc6d4c3a9 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -869,16 +869,17 @@ export class CodeWindow extends Disposable implements ICodeWindow { } private useNativeFullScreen(): boolean { - const windowConfig = this.configurationService.getValue('window'); - if (!windowConfig || typeof windowConfig.nativeFullScreen !== 'boolean') { - return true; // default - } + return true; + // const windowConfig = this.configurationService.getValue('window'); + // if (!windowConfig || typeof windowConfig.nativeFullScreen !== 'boolean') { + // return true; // default + // } - if (windowConfig.nativeTabs) { - return true; // https://github.com/electron/electron/issues/16142 - } + // if (windowConfig.nativeTabs) { + // return true; // https://github.com/electron/electron/issues/16142 + // } - return windowConfig.nativeFullScreen !== false; + // return windowConfig.nativeFullScreen !== false; } isMinimized(): boolean { diff --git a/src/vs/platform/windows/common/windows.ts b/src/vs/platform/windows/common/windows.ts index b8cf79dd68d0c..9075b9e74166d 100644 --- a/src/vs/platform/windows/common/windows.ts +++ b/src/vs/platform/windows/common/windows.ts @@ -300,7 +300,7 @@ export function getTitleBarStyle(configurationService: IConfigurationService, en return 'native'; // native tabs on sierra do not work with custom title style } - const useSimpleFullScreen = isMacintosh && configuration.nativeFullScreen === false; + const useSimpleFullScreen = false; //isMacintosh && configuration.nativeFullScreen === false; if (useSimpleFullScreen) { return 'native'; // simple fullscreen does not work well with custom title style (https://github.com/Microsoft/vscode/issues/63291) } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 9b217d89457f1..e6adc96847a35 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -560,7 +560,7 @@ import product from 'vs/platform/product/node/product'; 'default': true, 'description': nls.localize('window.nativeFullScreen', "Controls if native full-screen should be used on macOS. Disable this option to prevent macOS from creating a new space when going full-screen."), 'scope': ConfigurationScope.APPLICATION, - 'included': isMacintosh + 'included': false /* isMacintosh */ }, 'window.clickThroughInactive': { 'type': 'boolean', From 0de5cef5c72f095452c8d217ae56bd3e8de2e1ea Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 18:22:32 +0200 Subject: [PATCH 290/364] telemetry - add window.nativeFullScreen --- src/vs/platform/telemetry/common/telemetryUtils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index d9e73fab37cb4..e22844747989b 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -179,6 +179,7 @@ const configurationValueWhitelist = [ 'terminal.integrated.fontFamily', 'window.openFilesInNewWindow', 'window.restoreWindows', + 'window.nativeFullScreen', 'window.zoomLevel', 'workbench.editor.enablePreview', 'workbench.editor.enablePreviewFromQuickOpen', From e35db87ce7329cca6a2249f9a58479dfd81bbfa9 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 24 Jun 2019 18:32:18 +0200 Subject: [PATCH 291/364] move API to stable, #74188 --- src/vs/vscode.d.ts | 37 +++++++++++++++ src/vs/vscode.proposed.d.ts | 47 ------------------- src/vs/workbench/api/node/extHost.api.impl.ts | 1 - 3 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 8010b442641fc..953cfb9225952 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -4674,6 +4674,23 @@ declare module 'vscode' { dispose(): void; } + /** + * In a remote window the extension kind describes if an extension + * runs where the UI (window) runs or if an extension runs remotely. + */ + export enum ExtensionKind { + + /** + * Extension runs where the UI runs. + */ + UI = 1, + + /** + * Extension runs where the remote extension host runs. + */ + Workspace = 2 + } + /** * Represents an extension. * @@ -4701,6 +4718,15 @@ declare module 'vscode' { */ readonly packageJSON: any; + /** + * The extension kind describes if an extension runs where the UI runs + * or if an extension runs where the remote extension host runs. The extension kind + * if defined in the `package.json` file of extensions but can also be refined + * via the the `remote.extensionKind`-setting. When no remote extension host exists, + * the value is [`ExtensionKind.UI`](#ExtensionKind.UI). + */ + extensionKind: ExtensionKind; + /** * The public API exported by this extension. It is an invalid action * to access this field before this extension has been activated. @@ -6042,6 +6068,17 @@ declare module 'vscode' { */ export const sessionId: string; + /** + * The name of a remote. Defined by extensions, popular samples are `wsl` for the Windows + * Subsystem for Linux or `ssh-remote` for remotes using a secure shell. + * + * *Note* that the value is `undefined` when there is no remote extension host but that the + * value is defined in all extension hosts (local and remote) in case a remote extension host + * exists. Use [`Extension#extensionKind`](#Extension.extensionKind) to know if + * a specific extension runs remote or not. + */ + export const remoteName: string | undefined; + /** * Opens an *external* item, e.g. a http(s) or mailto-link, using the * default application. diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 272d73f670927..86d4ae370b651 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -27,53 +27,6 @@ declare module 'vscode' { } //#endregion - //#region Joh - ExtensionKind, vscode.env.remoteKind - - /** - * In a remote window the extension kind describes if an extension - * runs where the UI (window) runs or if an extension runs remotely. - */ - export enum ExtensionKind { - - /** - * Extension runs where the UI runs. - */ - UI = 1, - - /** - * Extension runs where the remote extension host runs. - */ - Workspace = 2 - } - - export interface Extension { - - /** - * The extension kind describes if an extension runs where the UI runs - * or if an extension runs where the remote extension host runs. The extension kind - * if defined in the `package.json` file of extensions but can also be refined - * via the the `remote.extensionKind`-setting. When no remote extension host exists, - * the value is [`ExtensionKind.UI`](#ExtensionKind.UI). - */ - extensionKind: ExtensionKind; - } - - export namespace env { - /** - * The name of a remote. Defined by extensions, popular samples are `wsl` for the Windows - * Subsystem for Linux or `ssh-remote` for remotes using a secure shell. - * - * *Note* that the value is `undefined` when there is no remote extension host but that the - * value is defined in all extension hosts (local and remote) in case a remote extension host - * exists. Use [`Extension#extensionKind`](#Extension.extensionKind) to know if - * a specific extension runs remote or not. - */ - export const remoteName: string | undefined; - } - - //#endregion - - //#region Joh - call hierarchy export enum CallHierarchyDirection { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 104c034e3fff5..9cff724bc75f9 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -267,7 +267,6 @@ export function createApiFactory( return initData.environment.webviewResourceRoot; }, get remoteName() { - checkProposedApiEnabled(extension); if (!initData.remote.authority) { return undefined; } From e42a1b0878b00be84365155240a29d04e20e9de4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 18:54:27 +0200 Subject: [PATCH 292/364] build - add and use --disable-inspect for integration tests (#74898) --- scripts/test-integration.bat | 14 ++++---- scripts/test-integration.sh | 10 +++--- .../environment/common/environment.ts | 1 + .../environment/node/environmentService.ts | 2 +- .../electron-browser/extensionHost.ts | 33 ++++++++----------- 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index 1c189ec7b1b3c..20567bc77cf75 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -10,25 +10,25 @@ call .\scripts\test.bat --runGlob **\*.integrationTest.js %* if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in the extension host -call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testWorkspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call .\scripts\code.bat %~dp0\..\extensions\vscode-api-tests\testworkspace.code-workspace --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\workspace-tests --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call .\scripts\code.bat %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% +call .\scripts\code.bat %~dp0\..\extensions\vscode-colorize-tests\test --extensionDevelopmentPath=%~dp0\..\extensions\vscode-colorize-tests --extensionTestsPath=%~dp0\..\extensions\vscode-colorize-tests\out --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% if %errorlevel% neq 0 exit /b %errorlevel% -call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disable-extensions --user-data-dir=%VSCODEUSERDATADIR% . +call .\scripts\code.bat $%~dp0\..\extensions\emmet\test-fixtures --extensionDevelopmentPath=%~dp0\..\extensions\emmet --extensionTestsPath=%~dp0\..\extensions\emmet\out\test --disable-extensions --disable-inspect --user-data-dir=%VSCODEUSERDATADIR% . if %errorlevel% neq 0 exit /b %errorlevel% :: Tests in commonJS (HTML, CSS, JSON language server tests...) call .\scripts\node-electron.bat .\node_modules\mocha\bin\_mocha .\extensions\*\server\out\test\**\*.test.js if %errorlevel% neq 0 exit /b %errorlevel% -REM if exist ".\resources\server\test\test-remote-integration.bat" ( -REM call .\resources\server\test\test-remote-integration.bat -REM ) +if exist ".\resources\server\test\test-remote-integration.bat" ( + call .\resources\server\test\test-remote-integration.bat +) rmdir /s /q %VSCODEUSERDATADIR% diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 3d397ed204ee7..7bb861252a719 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -16,13 +16,13 @@ cd $ROOT ./scripts/test.sh --runGlob **/*.integrationTest.js "$@" # Tests in the extension host -./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started -./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect +./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect +./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect +./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect mkdir -p $ROOT/extensions/emmet/test-fixtures -./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started +./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect rm -rf $ROOT/extensions/emmet/test-fixtures if [ -f ./resources/server/test/test-remote-integration.sh ]; then diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 210ac5080a35f..443e430fcd0e9 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -69,6 +69,7 @@ export interface ParsedArgs { remote?: string; 'disable-user-env-probe'?: boolean; 'enable-remote-auto-shutdown'?: boolean; + 'disable-inspect'?: boolean; } export const IEnvironmentService = createDecorator('environmentService'); diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 12881effa53fe..55c3d8302ae8c 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -294,7 +294,7 @@ export function parseSearchPort(args: ParsedArgs, isBuild: boolean): IDebugParam return parseDebugPort(args['inspect-search'], args['inspect-brk-search'], 5876, isBuild); } -export function parseDebugPort(debugArg: string | undefined, debugBrkArg: string | undefined, defaultBuildPort: number, isBuild: boolean, debugId?: string): IExtensionHostDebugParams { +function parseDebugPort(debugArg: string | undefined, debugBrkArg: string | undefined, defaultBuildPort: number, isBuild: boolean, debugId?: string): IExtensionHostDebugParams { const portStr = debugBrkArg || debugArg; const port = Number(portStr) || (!isBuild ? defaultBuildPort : null); const brk = port ? Boolean(!!debugBrkArg) : false; diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index bb552cc31d792..860845137fca0 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -57,7 +57,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { // Resources, in order they get acquired/created when .start() is called: private _namedPipeServer: Server | null; - private _inspectPort: number; + private _inspectPort: number | null; private _extensionHostProcess: ChildProcess | null; private _extensionHostConnection: Socket | null; private _messageProtocol: Promise | null; @@ -123,7 +123,10 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { } if (!this._messageProtocol) { - this._messageProtocol = Promise.all([this._tryListenOnPipe(), this._tryFindDebugPort()]).then(data => { + this._messageProtocol = Promise.all([ + this._tryListenOnPipe(), + !this._environmentService.args['disable-inspect'] ? this._tryFindDebugPort() : Promise.resolve(null) + ]).then(data => { const pipeName = data[0]; const portData = data[1]; @@ -146,7 +149,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { silent: true }; - if (portData.actual) { + if (portData && portData.actual) { opts.execArgv = [ '--nolazy', (this._isExtensionDevDebugBrk ? '--inspect-brk=' : '--inspect=') + portData.actual @@ -213,10 +216,12 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._extensionHostProcess.on('exit', (code: number, signal: string) => this._onExtHostProcessExit(code, signal)); // Notify debugger that we are ready to attach to the process if we run a development extension - if (this._isExtensionDevHost && portData.actual && this._isExtensionDevDebug && this._environmentService.debugExtensionHost.debugId) { - this._extensionHostDebugService.attachSession(this._environmentService.debugExtensionHost.debugId, portData.actual); + if (portData) { + if (this._isExtensionDevHost && portData.actual && this._isExtensionDevDebug && this._environmentService.debugExtensionHost.debugId) { + this._extensionHostDebugService.attachSession(this._environmentService.debugExtensionHost.debugId, portData.actual); + } + this._inspectPort = portData.actual; } - this._inspectPort = portData.actual; // Help in case we fail to start it let startupTimeoutHandle: any; @@ -457,20 +462,8 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { this._onExit.fire([code, signal]); } - public enableInspector(): Promise { - if (this._inspectPort) { - return Promise.resolve(); - } - // send SIGUSR1 and wait a little the actual port is read from the process stdout which we - // scan here: https://github.com/Microsoft/vscode/blob/67ffab8dcd1a6752d8b62bcd13d7020101eef568/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts#L225-L240 - if (this._extensionHostProcess) { - this._extensionHostProcess.kill('SIGUSR1'); - } - return timeout(1000); - } - - public getInspectPort(): number { - return this._inspectPort; + public getInspectPort(): number | undefined { + return withNullAsUndefined(this._inspectPort); } public terminate(): void { From b2a456e7f9402e966513cb7d74a5a94024b61e0f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 18:57:37 +0200 Subject: [PATCH 293/364] :lipstick: --- scripts/test-integration.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/test-integration.sh b/scripts/test-integration.sh index 7bb861252a719..45595a5f0a387 100755 --- a/scripts/test-integration.sh +++ b/scripts/test-integration.sh @@ -16,13 +16,13 @@ cd $ROOT ./scripts/test.sh --runGlob **/*.integrationTest.js "$@" # Tests in the extension host -./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect -./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect -./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect -./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect +./scripts/code.sh $ROOT/extensions/vscode-api-tests/testWorkspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR +./scripts/code.sh $ROOT/extensions/vscode-api-tests/testworkspace.code-workspace --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/workspace-tests --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR +./scripts/code.sh $ROOT/extensions/vscode-colorize-tests/test --extensionDevelopmentPath=$ROOT/extensions/vscode-colorize-tests --extensionTestsPath=$ROOT/extensions/vscode-colorize-tests/out --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR +./scripts/code.sh $ROOT/extensions/markdown-language-features/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/markdown-language-features --extensionTestsPath=$ROOT/extensions/markdown-language-features/out/test --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR mkdir -p $ROOT/extensions/emmet/test-fixtures -./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --user-data-dir=$VSCODEUSERDATADIR --skip-getting-started --disable-inspect +./scripts/code.sh $ROOT/extensions/emmet/test-fixtures --extensionDevelopmentPath=$ROOT/extensions/emmet --extensionTestsPath=$ROOT/extensions/emmet/out/test --disable-extensions --skip-getting-started --disable-inspect --user-data-dir=$VSCODEUSERDATADIR rm -rf $ROOT/extensions/emmet/test-fixtures if [ -f ./resources/server/test/test-remote-integration.sh ]; then From ae057d43a88dd5dafa23a203e05441f08c612855 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 24 Jun 2019 19:00:38 +0200 Subject: [PATCH 294/364] bump distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bbd1ab905cef4..7755b30ebef3c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "d2c482aba7912623c65fa4da1ea722f32558197c", + "distro": "6e5b8dfbbda7ce121811e397d16842251bd666aa", "author": { "name": "Microsoft Corporation" }, From 3a6605a3c0da06c4008880976673002c202f90d8 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 24 Jun 2019 10:25:30 -0700 Subject: [PATCH 295/364] Report workspace stats in shared process --- .../sharedProcess/sharedProcessMain.ts | 13 +- src/vs/code/electron-main/app.ts | 6 + src/vs/code/electron-main/main.ts | 11 +- .../diagnostics/common/diagnosticsService.ts | 21 + .../electron-main/diagnosticsService.ts | 389 ---------------- .../diagnostics/node/diagnosticsIpc.ts | 58 +++ .../diagnostics/node/diagnosticsService.ts | 420 +++++++++++++++++- .../issue/electron-main/issueService.ts | 43 +- .../platform/launch/common/launchService.ts | 21 + .../launch/electron-main/launchService.ts | 23 +- .../experimentService.ts | 2 +- .../electron-browser/experimentalPrompt.ts | 2 +- .../experiments.contribution.ts | 2 +- .../experimentService.test.ts | 2 +- .../experimentalPrompts.test.ts | 2 +- .../electron-browser/extensionTipsService.ts | 4 +- .../electron-browser/extensionsViews.ts | 2 +- .../extensionsTipsService.test.ts | 2 +- .../electron-browser/extensionsViews.test.ts | 2 +- .../stats.contribution.ts | 2 +- .../workspaceStats.ts | 7 +- .../contrib/stats/test/workspaceStats.test.ts | 2 +- .../electron-browser/telemetryOptOut.ts | 2 +- src/vs/workbench/workbench.main.ts | 2 +- 24 files changed, 576 insertions(+), 464 deletions(-) delete mode 100644 src/vs/platform/diagnostics/electron-main/diagnosticsService.ts create mode 100644 src/vs/platform/diagnostics/node/diagnosticsIpc.ts create mode 100644 src/vs/platform/launch/common/launchService.ts rename src/vs/workbench/contrib/experiments/{node => electron-browser}/experimentService.ts (99%) rename src/vs/workbench/contrib/stats/{node => electron-browser}/stats.contribution.ts (89%) rename src/vs/workbench/contrib/stats/{node => electron-browser}/workspaceStats.ts (98%) diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 34cd3e48a63ed..c1cda36142320 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -48,6 +48,9 @@ import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/ import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; +import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; +import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { DiagnosticsChannel } from 'vs/platform/diagnostics/node/diagnosticsIpc'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -121,6 +124,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat const instantiationService = new InstantiationService(services); + let telemetryService: ITelemetryService; instantiationService.invokeFunction(accessor => { const services = new ServiceCollection(); const environmentService = accessor.get(IEnvironmentService); @@ -141,8 +145,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat piiPaths: [appRoot, extensionsPath] }; - services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config])); + telemetryService = new TelemetryService(config, configurationService); + services.set(ITelemetryService, telemetryService); } else { + telemetryService = NullTelemetryService; services.set(ITelemetryService, NullTelemetryService); } server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appInsightsAppender)); @@ -150,6 +156,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService)); + services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService)); const instantiationService2 = instantiationService.createChild(services); @@ -163,6 +170,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat const localizationsChannel = new LocalizationsChannel(localizationsService); server.registerChannel('localizations', localizationsChannel); + const diagnosticsService = accessor.get(IDiagnosticsService); + const diagnosticsChannel = new DiagnosticsChannel(diagnosticsService); + server.registerChannel('diagnostics', diagnosticsChannel); + // clean up deprecated extensions (extensionManagementService as ExtensionManagementService).removeDeprecatedExtensions(); // update localizations cache diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index a829266dc516c..e9afa5d4ae626 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -81,6 +81,8 @@ import { nodeWebSocketFactory } from 'vs/platform/remote/node/nodeWebSocketFacto import { VSBuffer } from 'vs/base/common/buffer'; import { statSync } from 'fs'; import { ISignService } from 'vs/platform/sign/common/sign'; +import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; export class CodeApplication extends Disposable { @@ -407,6 +409,10 @@ export class CodeApplication extends Disposable { services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv])); services.set(IWindowsService, new SyncDescriptor(WindowsService, [sharedProcess])); services.set(ILaunchService, new SyncDescriptor(LaunchService)); + + const diagnosticsChannel = getDelayedChannel(sharedProcessClient.then(client => client.getChannel('diagnostics'))); + services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService, [diagnosticsChannel])); + services.set(IIssueService, new SyncDescriptor(IssueService, [machineId, this.userEnv])); services.set(IMenubarService, new SyncDescriptor(MenubarService)); diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index be40bfa20d075..97578e1925239 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -33,7 +33,6 @@ import { CodeApplication } from 'vs/code/electron-main/app'; import { localize } from 'vs/nls'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; -import { IDiagnosticsService, DiagnosticsService } from 'vs/platform/diagnostics/electron-main/diagnosticsService'; import { BufferLogService } from 'vs/platform/log/common/bufferLog'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { IThemeMainService, ThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; @@ -41,6 +40,7 @@ import { Client } from 'vs/base/parts/ipc/common/ipc.net'; import { once } from 'vs/base/common/functional'; import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/node/signService'; +import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; class ExpectedError extends Error { readonly isExpected = true; @@ -146,7 +146,6 @@ class CodeMain { services.set(ILifecycleService, new SyncDescriptor(LifecycleService)); services.set(IStateService, new SyncDescriptor(StateService)); services.set(IRequestService, new SyncDescriptor(RequestService)); - services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService)); services.set(IThemeMainService, new SyncDescriptor(ThemeMainService)); services.set(ISignService, new SyncDescriptor(SignService)); @@ -277,7 +276,13 @@ class CodeMain { // Process Info if (environmentService.args.status) { return instantiationService.invokeFunction(async accessor => { - const diagnostics = await accessor.get(IDiagnosticsService).getDiagnostics(launchClient); + // Create a diagnostic service connected to the existing shared process + const sharedProcessClient = await connect(environmentService.sharedIPCHandle, 'main'); + const diagnosticsChannel = sharedProcessClient.getChannel('diagnostics'); + const diagnosticsService = new DiagnosticsService(diagnosticsChannel); + const mainProcessInfo = await launchClient.getMainProcessInfo(); + const remoteDiagnostics = await launchClient.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true }); + const diagnostics = await diagnosticsService.getDiagnostics(mainProcessInfo, remoteDiagnostics); console.log(diagnostics); throw new ExpectedError(); diff --git a/src/vs/platform/diagnostics/common/diagnosticsService.ts b/src/vs/platform/diagnostics/common/diagnosticsService.ts index 21cd8952e13cd..496b75397c031 100644 --- a/src/vs/platform/diagnostics/common/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/common/diagnosticsService.ts @@ -5,6 +5,9 @@ import { UriComponents } from 'vs/base/common/uri'; import { ProcessItem } from 'vs/base/common/processes'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; +import { IWorkspace } from 'vs/platform/workspace/common/workspace'; export interface IMachineInfo { os: string; @@ -51,6 +54,24 @@ export interface WorkspaceStats { configFiles: WorkspaceStatItem[]; fileCount: number; maxFilesReached: boolean; + launchConfigFiles: WorkspaceStatItem[]; +} + +export interface PerformanceInfo { + processInfo?: string; + workspaceInfo?: string; +} + +export const ID = 'diagnosticsService'; +export const IDiagnosticsService = createDecorator(ID); + +export interface IDiagnosticsService { + _serviceBrand: any; + + getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; + getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; + getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise; + reportWorkspaceStats(workspace: IWorkspace): Promise; } export function isRemoteDiagnosticError(x: any): x is IRemoteDiagnosticError { diff --git a/src/vs/platform/diagnostics/electron-main/diagnosticsService.ts b/src/vs/platform/diagnostics/electron-main/diagnosticsService.ts deleted file mode 100644 index 1b7eb413e8cf8..0000000000000 --- a/src/vs/platform/diagnostics/electron-main/diagnosticsService.ts +++ /dev/null @@ -1,389 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IMainProcessInfo, ILaunchService } from 'vs/platform/launch/electron-main/launchService'; -import { listProcesses } from 'vs/base/node/ps'; -import product from 'vs/platform/product/node/product'; -import pkg from 'vs/platform/product/node/package'; -import * as osLib from 'os'; -import { virtualMachineHint } from 'vs/base/node/id'; -import { repeat, pad } from 'vs/base/common/strings'; -import { isWindows } from 'vs/base/common/platform'; -import { app } from 'electron'; -import { basename } from 'vs/base/common/path'; -import { URI } from 'vs/base/common/uri'; -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IMachineInfo, WorkspaceStats, SystemInfo, IRemoteDiagnosticInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; -import { collectWorkspaceStats, getMachineInfo } from 'vs/platform/diagnostics/node/diagnosticsService'; -import { ProcessItem } from 'vs/base/common/processes'; - -export const ID = 'diagnosticsService'; -export const IDiagnosticsService = createDecorator(ID); - -export interface IDiagnosticsService { - _serviceBrand: any; - - getPerformanceInfo(launchService: ILaunchService): Promise; - getSystemInfo(launchService: ILaunchService): Promise; - getDiagnostics(launchService: ILaunchService): Promise; -} - -export interface VersionInfo { - vscodeVersion: string; - os: string; -} - -export interface ProcessInfo { - cpu: number; - memory: number; - pid: number; - name: string; -} - -export interface PerformanceInfo { - processInfo?: string; - workspaceInfo?: string; -} -export class DiagnosticsService implements IDiagnosticsService { - - _serviceBrand: any; - - private formatMachineInfo(info: IMachineInfo): string { - const output: string[] = []; - output.push(`OS Version: ${info.os}`); - output.push(`CPUs: ${info.cpus}`); - output.push(`Memory (System): ${info.memory}`); - output.push(`VM: ${info.vmHint}`); - - return output.join('\n'); - } - - private formatEnvironment(info: IMainProcessInfo): string { - const MB = 1024 * 1024; - const GB = 1024 * MB; - - const output: string[] = []; - output.push(`Version: ${pkg.name} ${pkg.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`); - output.push(`OS Version: ${osLib.type()} ${osLib.arch()} ${osLib.release()}`); - const cpus = osLib.cpus(); - if (cpus && cpus.length > 0) { - output.push(`CPUs: ${cpus[0].model} (${cpus.length} x ${cpus[0].speed})`); - } - output.push(`Memory (System): ${(osLib.totalmem() / GB).toFixed(2)}GB (${(osLib.freemem() / GB).toFixed(2)}GB free)`); - if (!isWindows) { - output.push(`Load (avg): ${osLib.loadavg().map(l => Math.round(l)).join(', ')}`); // only provided on Linux/macOS - } - output.push(`VM: ${Math.round((virtualMachineHint.value() * 100))}%`); - output.push(`Screen Reader: ${app.isAccessibilitySupportEnabled() ? 'yes' : 'no'}`); - output.push(`Process Argv: ${info.mainArguments.join(' ')}`); - output.push(`GPU Status: ${this.expandGPUFeatures()}`); - - return output.join('\n'); - } - - async getPerformanceInfo(launchService: ILaunchService): Promise { - const info = await launchService.getMainProcessInfo(); - return Promise.all([listProcesses(info.mainPID), this.formatWorkspaceMetadata(info)]).then(async result => { - let [rootProcess, workspaceInfo] = result; - let processInfo = this.formatProcessList(info, rootProcess); - - try { - const remoteData = await launchService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true }); - remoteData.forEach(diagnostics => { - if (isRemoteDiagnosticError(diagnostics)) { - processInfo += `\n${diagnostics.errorMessage}`; - workspaceInfo += `\n${diagnostics.errorMessage}`; - } else { - processInfo += `\n\nRemote: ${diagnostics.hostName}`; - if (diagnostics.processes) { - processInfo += `\n${this.formatProcessList(info, diagnostics.processes)}`; - } - - if (diagnostics.workspaceMetadata) { - workspaceInfo += `\n| Remote: ${diagnostics.hostName}`; - for (const folder of Object.keys(diagnostics.workspaceMetadata)) { - const metadata = diagnostics.workspaceMetadata[folder]; - - let countMessage = `${metadata.fileCount} files`; - if (metadata.maxFilesReached) { - countMessage = `more than ${countMessage}`; - } - - workspaceInfo += `| Folder (${folder}): ${countMessage}`; - workspaceInfo += this.formatWorkspaceStats(metadata); - } - } - } - }); - } catch (e) { - processInfo += `\nFetching remote data failed: ${e}`; - workspaceInfo += `\nFetching remote data failed: ${e}`; - } - - return { - processInfo, - workspaceInfo - }; - }); - } - - async getSystemInfo(launchService: ILaunchService): Promise { - const info = await launchService.getMainProcessInfo(); - const { memory, vmHint, os, cpus } = getMachineInfo(); - const systemInfo: SystemInfo = { - os, - memory, - cpus, - vmHint, - processArgs: `${info.mainArguments.join(' ')}`, - gpuStatus: app.getGPUFeatureStatus(), - screenReader: `${app.isAccessibilitySupportEnabled() ? 'yes' : 'no'}`, - remoteData: (await launchService.getRemoteDiagnostics({ includeProcesses: false, includeWorkspaceMetadata: false })).filter((x): x is IRemoteDiagnosticInfo => !(x instanceof Error)) - }; - - - if (!isWindows) { - systemInfo.load = `${osLib.loadavg().map(l => Math.round(l)).join(', ')}`; - } - - return Promise.resolve(systemInfo); - } - - async getDiagnostics(launchService: ILaunchService): Promise { - const output: string[] = []; - const info = await launchService.getMainProcessInfo(); - return listProcesses(info.mainPID).then(async rootProcess => { - - // Environment Info - output.push(''); - output.push(this.formatEnvironment(info)); - - // Process List - output.push(''); - output.push(this.formatProcessList(info, rootProcess)); - - // Workspace Stats - if (info.windows.some(window => window.folderURIs && window.folderURIs.length > 0 && !window.remoteAuthority)) { - output.push(''); - output.push('Workspace Stats: '); - output.push(await this.formatWorkspaceMetadata(info)); - } - - try { - const data = await launchService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true }); - data.forEach(diagnostics => { - if (isRemoteDiagnosticError(diagnostics)) { - output.push(`\n${diagnostics.errorMessage}`); - } else { - output.push('\n\n'); - output.push(`Remote: ${diagnostics.hostName}`); - output.push(this.formatMachineInfo(diagnostics.machineInfo)); - - if (diagnostics.processes) { - output.push(this.formatProcessList(info, diagnostics.processes)); - } - - if (diagnostics.workspaceMetadata) { - for (const folder of Object.keys(diagnostics.workspaceMetadata)) { - const metadata = diagnostics.workspaceMetadata[folder]; - - let countMessage = `${metadata.fileCount} files`; - if (metadata.maxFilesReached) { - countMessage = `more than ${countMessage}`; - } - - output.push(`Folder (${folder}): ${countMessage}`); - output.push(this.formatWorkspaceStats(metadata)); - } - } - } - }); - } catch (e) { - output.push('\n\n'); - output.push(`Fetching status information from remotes failed: ${e.message}`); - } - - output.push(''); - output.push(''); - - return output.join('\n'); - }); - } - - private formatWorkspaceStats(workspaceStats: WorkspaceStats): string { - const output: string[] = []; - const lineLength = 60; - let col = 0; - - const appendAndWrap = (name: string, count: number) => { - const item = ` ${name}(${count})`; - - if (col + item.length > lineLength) { - output.push(line); - line = '| '; - col = line.length; - } - else { - col += item.length; - } - line += item; - }; - - // File Types - let line = '| File types:'; - const maxShown = 10; - let max = workspaceStats.fileTypes.length > maxShown ? maxShown : workspaceStats.fileTypes.length; - for (let i = 0; i < max; i++) { - const item = workspaceStats.fileTypes[i]; - appendAndWrap(item.name, item.count); - } - output.push(line); - - // Conf Files - if (workspaceStats.configFiles.length >= 0) { - line = '| Conf files:'; - col = 0; - workspaceStats.configFiles.forEach((item) => { - appendAndWrap(item.name, item.count); - }); - output.push(line); - } - - // if (workspaceStats.launchConfigFiles.length > 0) { - // let line = '| Launch Configs:'; - // workspaceStats.launchConfigFiles.forEach(each => { - // const item = each.count > 1 ? ` ${each.name}(${each.count})` : ` ${each.name}`; - // line += item; - // }); - // output.push(line); - // } - return output.join('\n'); - } - - private expandGPUFeatures(): string { - const gpuFeatures = app.getGPUFeatureStatus(); - const longestFeatureName = Math.max(...Object.keys(gpuFeatures).map(feature => feature.length)); - // Make columns aligned by adding spaces after feature name - return Object.keys(gpuFeatures).map(feature => `${feature}: ${repeat(' ', longestFeatureName - feature.length)} ${gpuFeatures[feature]}`).join('\n '); - } - - private formatWorkspaceMetadata(info: IMainProcessInfo): Promise { - const output: string[] = []; - const workspaceStatPromises: Promise[] = []; - - info.windows.forEach(window => { - if (window.folderURIs.length === 0 || !!window.remoteAuthority) { - return; - } - - output.push(`| Window (${window.title})`); - - window.folderURIs.forEach(uriComponents => { - const folderUri = URI.revive(uriComponents); - if (folderUri.scheme === 'file') { - const folder = folderUri.fsPath; - workspaceStatPromises.push(collectWorkspaceStats(folder, ['node_modules', '.git']).then(stats => { - let countMessage = `${stats.fileCount} files`; - if (stats.maxFilesReached) { - countMessage = `more than ${countMessage}`; - } - output.push(`| Folder (${basename(folder)}): ${countMessage}`); - output.push(this.formatWorkspaceStats(stats)); - - }).catch(error => { - output.push(`| Error: Unable to collect workspace stats for folder ${folder} (${error.toString()})`); - })); - } else { - output.push(`| Folder (${folderUri.toString()}): Workspace stats not available.`); - } - }); - }); - - return Promise.all(workspaceStatPromises) - .then(_ => output.join('\n')) - .catch(e => `Unable to collect workspace stats: ${e}`); - } - - private formatProcessList(info: IMainProcessInfo, rootProcess: ProcessItem): string { - const mapPidToWindowTitle = new Map(); - info.windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title)); - - const output: string[] = []; - - output.push('CPU %\tMem MB\t PID\tProcess'); - - if (rootProcess) { - this.formatProcessItem(info.mainPID, mapPidToWindowTitle, output, rootProcess, 0); - } - - return output.join('\n'); - } - - private formatProcessItem(mainPid: number, mapPidToWindowTitle: Map, output: string[], item: ProcessItem, indent: number): void { - const isRoot = (indent === 0); - - const MB = 1024 * 1024; - - // Format name with indent - let name: string; - if (isRoot) { - name = item.pid === mainPid ? `${product.applicationName} main` : 'remote agent'; - } else { - name = `${repeat(' ', indent)} ${item.name}`; - - if (item.name === 'window') { - name = `${name} (${mapPidToWindowTitle.get(item.pid)})`; - } - } - const memory = process.platform === 'win32' ? item.mem : (osLib.totalmem() * (item.mem / 100)); - output.push(`${pad(Number(item.load.toFixed(0)), 5, ' ')}\t${pad(Number((memory / MB).toFixed(0)), 6, ' ')}\t${pad(Number((item.pid).toFixed(0)), 6, ' ')}\t${name}`); - - // Recurse into children if any - if (Array.isArray(item.children)) { - item.children.forEach(child => this.formatProcessItem(mainPid, mapPidToWindowTitle, output, child, indent + 1)); - } - } -} - -// function collectLaunchConfigs(folder: string): Promise { -// const launchConfigs = new Map(); - -// const launchConfig = join(folder, '.vscode', 'launch.json'); -// return new Promise((resolve, reject) => { -// exists(launchConfig, (doesExist) => { -// if (doesExist) { -// readFile(launchConfig, (err, contents) => { -// if (err) { -// return resolve([]); -// } - -// const errors: ParseError[] = []; -// const json = parse(contents.toString(), errors); -// if (errors.length) { -// output.push(`Unable to parse ${launchConfig}`); -// return resolve([]); -// } - -// if (json['configurations']) { -// for (const each of json['configurations']) { -// const type = each['type']; -// if (type) { -// if (launchConfigs.has(type)) { -// launchConfigs.set(type, launchConfigs.get(type)! + 1); -// } else { -// launchConfigs.set(type, 1); -// } -// } -// } -// } - -// return resolve(asSortedItems(launchConfigs)); -// }); -// } else { -// return resolve([]); -// } -// }); -// }); -// } diff --git a/src/vs/platform/diagnostics/node/diagnosticsIpc.ts b/src/vs/platform/diagnostics/node/diagnosticsIpc.ts new file mode 100644 index 0000000000000..28cabc55e7b14 --- /dev/null +++ b/src/vs/platform/diagnostics/node/diagnosticsIpc.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IDiagnosticsService, IRemoteDiagnosticInfo, IRemoteDiagnosticError, SystemInfo, PerformanceInfo } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { Event } from 'vs/base/common/event'; +import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; +import { IWorkspace } from 'vs/platform/workspace/common/workspace'; + +export class DiagnosticsChannel implements IServerChannel { + + constructor(private service: IDiagnosticsService) { } + + listen(context: any, event: string): Event { + throw new Error('Invalid listen'); + } + + call(context: any, command: string, args?: any): Promise { + switch (command) { + case 'getDiagnostics': + return this.service.getDiagnostics(args[0], args[1]); + case 'getSystemInfo': + return this.service.getSystemInfo(args[0], args[1]); + case 'getPerformanceInfo': + return this.service.getPerformanceInfo(args[0], args[1]); + case 'reportWorkspaceStats': + return this.service.reportWorkspaceStats(args); + } + + throw new Error('Invalid call'); + } +} + +export class DiagnosticsService implements IDiagnosticsService { + + _serviceBrand: ServiceIdentifier; + + constructor(private channel: IChannel) { } + + public getDiagnostics(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise { + return this.channel.call('getDiagnostics', [mainProcessInfo, remoteInfo]); + } + + public getSystemInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise { + return this.channel.call('getSystemInfo', [mainProcessInfo, remoteInfo]); + } + + public getPerformanceInfo(mainProcessInfo: IMainProcessInfo, remoteInfo: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise { + return this.channel.call('getPerformanceInfo', [mainProcessInfo, remoteInfo]); + } + + public reportWorkspaceStats(workspace: IWorkspace): Promise { + return this.channel.call('reportWorkspaceStats', workspace); + } +} \ No newline at end of file diff --git a/src/vs/platform/diagnostics/node/diagnosticsService.ts b/src/vs/platform/diagnostics/node/diagnosticsService.ts index ae056538ab9f2..9fd4e15fea774 100644 --- a/src/vs/platform/diagnostics/node/diagnosticsService.ts +++ b/src/vs/platform/diagnostics/node/diagnosticsService.ts @@ -2,28 +2,33 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as os from 'os'; +import * as osLib from 'os'; import { virtualMachineHint } from 'vs/base/node/id'; -import { IMachineInfo, WorkspaceStats, WorkspaceStatItem } from 'vs/platform/diagnostics/common/diagnosticsService'; -import { readdir, stat } from 'fs'; -import { join } from 'vs/base/common/path'; +import { IMachineInfo, WorkspaceStats, WorkspaceStatItem, IDiagnosticsService, PerformanceInfo, SystemInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { readdir, stat, exists, readFile } from 'fs'; +import { join, basename } from 'vs/base/common/path'; +import { parse, ParseError } from 'vs/base/common/json'; +import { listProcesses } from 'vs/base/node/ps'; +import product from 'vs/platform/product/node/product'; +import pkg from 'vs/platform/product/node/package'; +import { repeat, pad } from 'vs/base/common/strings'; +import { isWindows } from 'vs/base/common/platform'; +import { URI } from 'vs/base/common/uri'; +import { ProcessItem } from 'vs/base/common/processes'; +import { IMainProcessInfo } from 'vs/platform/launch/common/launchService'; +import { IWorkspace } from 'vs/platform/workspace/common/workspace'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -export function getMachineInfo(): IMachineInfo { - const MB = 1024 * 1024; - const GB = 1024 * MB; - - const machineInfo: IMachineInfo = { - os: `${os.type()} ${os.arch()} ${os.release()}`, - memory: `${(os.totalmem() / GB).toFixed(2)}GB (${(os.freemem() / GB).toFixed(2)}GB free)`, - vmHint: `${Math.round((virtualMachineHint.value() * 100))}%`, - }; - - const cpus = os.cpus(); - if (cpus && cpus.length > 0) { - machineInfo.cpus = `${cpus[0].model} (${cpus.length} x ${cpus[0].speed})`; - } +export interface VersionInfo { + vscodeVersion: string; + os: string; +} - return machineInfo; +export interface ProcessInfo { + cpu: number; + memory: number; + pid: number; + name: string; } export function collectWorkspaceStats(folder: string, filter: string[]): Promise { @@ -145,16 +150,14 @@ export function collectWorkspaceStats(folder: string, filter: string[]): Promise walk(folder, filter, token, async (files) => { files.forEach(acceptFile); - // TODO@rachel commented out due to severe performance issues - // see https://github.com/Microsoft/vscode/issues/70563 - // const launchConfigs = await collectLaunchConfigs(folder); + const launchConfigs = await collectLaunchConfigs(folder); resolve({ configFiles: asSortedItems(configFiles), fileTypes: asSortedItems(fileTypes), fileCount: token.count, maxFilesReached: token.maxReached, - // launchConfigFiles: launchConfigs + launchConfigFiles: launchConfigs }); }); }); @@ -164,4 +167,375 @@ function asSortedItems(map: Map): WorkspaceStatItem[] { const a: WorkspaceStatItem[] = []; map.forEach((value, index) => a.push({ name: index, count: value })); return a.sort((a, b) => b.count - a.count); +} + +export function getMachineInfo(): IMachineInfo { + const MB = 1024 * 1024; + const GB = 1024 * MB; + + const machineInfo: IMachineInfo = { + os: `${osLib.type()} ${osLib.arch()} ${osLib.release()}`, + memory: `${(osLib.totalmem() / GB).toFixed(2)}GB (${(osLib.freemem() / GB).toFixed(2)}GB free)`, + vmHint: `${Math.round((virtualMachineHint.value() * 100))}%`, + }; + + const cpus = osLib.cpus(); + if (cpus && cpus.length > 0) { + machineInfo.cpus = `${cpus[0].model} (${cpus.length} x ${cpus[0].speed})`; + } + + return machineInfo; +} + +export function collectLaunchConfigs(folder: string): Promise { + let launchConfigs = new Map(); + + let launchConfig = join(folder, '.vscode', 'launch.json'); + return new Promise((resolve, reject) => { + exists(launchConfig, (doesExist) => { + if (doesExist) { + readFile(launchConfig, (err, contents) => { + if (err) { + return resolve([]); + } + + const errors: ParseError[] = []; + const json = parse(contents.toString(), errors); + if (errors.length) { + console.log(`Unable to parse ${launchConfig}`); + return resolve([]); + } + + if (json['configurations']) { + for (const each of json['configurations']) { + const type = each['type']; + if (type) { + if (launchConfigs.has(type)) { + launchConfigs.set(type, launchConfigs.get(type)! + 1); + } else { + launchConfigs.set(type, 1); + } + } + } + } + + return resolve(asSortedItems(launchConfigs)); + }); + } else { + return resolve([]); + } + }); + }); +} + +export class DiagnosticsService implements IDiagnosticsService { + + _serviceBrand: any; + + constructor(@ITelemetryService private readonly telemetryService: ITelemetryService) { } + + private formatMachineInfo(info: IMachineInfo): string { + const output: string[] = []; + output.push(`OS Version: ${info.os}`); + output.push(`CPUs: ${info.cpus}`); + output.push(`Memory (System): ${info.memory}`); + output.push(`VM: ${info.vmHint}`); + + return output.join('\n'); + } + + private formatEnvironment(info: IMainProcessInfo): string { + const MB = 1024 * 1024; + const GB = 1024 * MB; + + const output: string[] = []; + output.push(`Version: ${pkg.name} ${pkg.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`); + output.push(`OS Version: ${osLib.type()} ${osLib.arch()} ${osLib.release()}`); + const cpus = osLib.cpus(); + if (cpus && cpus.length > 0) { + output.push(`CPUs: ${cpus[0].model} (${cpus.length} x ${cpus[0].speed})`); + } + output.push(`Memory (System): ${(osLib.totalmem() / GB).toFixed(2)}GB (${(osLib.freemem() / GB).toFixed(2)}GB free)`); + if (!isWindows) { + output.push(`Load (avg): ${osLib.loadavg().map(l => Math.round(l)).join(', ')}`); // only provided on Linux/macOS + } + output.push(`VM: ${Math.round((virtualMachineHint.value() * 100))}%`); + output.push(`Screen Reader: ${info.screenReader ? 'yes' : 'no'}`); + output.push(`Process Argv: ${info.mainArguments.join(' ')}`); + output.push(`GPU Status: ${this.expandGPUFeatures(info.gpuFeatureStatus)}`); + + return output.join('\n'); + } + + public async getPerformanceInfo(info: IMainProcessInfo, remoteData: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise { + return Promise.all([listProcesses(info.mainPID), this.formatWorkspaceMetadata(info)]).then(async result => { + let [rootProcess, workspaceInfo] = result; + let processInfo = this.formatProcessList(info, rootProcess); + + remoteData.forEach(diagnostics => { + if (isRemoteDiagnosticError(diagnostics)) { + processInfo += `\n${diagnostics.errorMessage}`; + workspaceInfo += `\n${diagnostics.errorMessage}`; + } else { + processInfo += `\n\nRemote: ${diagnostics.hostName}`; + if (diagnostics.processes) { + processInfo += `\n${this.formatProcessList(info, diagnostics.processes)}`; + } + + if (diagnostics.workspaceMetadata) { + workspaceInfo += `\n| Remote: ${diagnostics.hostName}`; + for (const folder of Object.keys(diagnostics.workspaceMetadata)) { + const metadata = diagnostics.workspaceMetadata[folder]; + + let countMessage = `${metadata.fileCount} files`; + if (metadata.maxFilesReached) { + countMessage = `more than ${countMessage}`; + } + + workspaceInfo += `| Folder (${folder}): ${countMessage}`; + workspaceInfo += this.formatWorkspaceStats(metadata); + } + } + } + }); + + return { + processInfo, + workspaceInfo + }; + }); + } + + public async getSystemInfo(info: IMainProcessInfo, remoteData: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise { + const { memory, vmHint, os, cpus } = getMachineInfo(); + const systemInfo: SystemInfo = { + os, + memory, + cpus, + vmHint, + processArgs: `${info.mainArguments.join(' ')}`, + gpuStatus: info.gpuFeatureStatus, + screenReader: `${info.screenReader ? 'yes' : 'no'}`, + remoteData + }; + + + if (!isWindows) { + systemInfo.load = `${osLib.loadavg().map(l => Math.round(l)).join(', ')}`; + } + + return Promise.resolve(systemInfo); + } + + public async getDiagnostics(info: IMainProcessInfo, remoteDiagnostics: (IRemoteDiagnosticInfo | IRemoteDiagnosticError)[]): Promise { + const output: string[] = []; + return listProcesses(info.mainPID).then(async rootProcess => { + + // Environment Info + output.push(''); + output.push(this.formatEnvironment(info)); + + // Process List + output.push(''); + output.push(this.formatProcessList(info, rootProcess)); + + // Workspace Stats + if (info.windows.some(window => window.folderURIs && window.folderURIs.length > 0 && !window.remoteAuthority)) { + output.push(''); + output.push('Workspace Stats: '); + output.push(await this.formatWorkspaceMetadata(info)); + } + + remoteDiagnostics.forEach(diagnostics => { + if (isRemoteDiagnosticError(diagnostics)) { + output.push(`\n${diagnostics.errorMessage}`); + } else { + output.push('\n\n'); + output.push(`Remote: ${diagnostics.hostName}`); + output.push(this.formatMachineInfo(diagnostics.machineInfo)); + + if (diagnostics.processes) { + output.push(this.formatProcessList(info, diagnostics.processes)); + } + + if (diagnostics.workspaceMetadata) { + for (const folder of Object.keys(diagnostics.workspaceMetadata)) { + const metadata = diagnostics.workspaceMetadata[folder]; + + let countMessage = `${metadata.fileCount} files`; + if (metadata.maxFilesReached) { + countMessage = `more than ${countMessage}`; + } + + output.push(`Folder (${folder}): ${countMessage}`); + output.push(this.formatWorkspaceStats(metadata)); + } + } + } + }); + + output.push(''); + output.push(''); + + return output.join('\n'); + }); + } + + private formatWorkspaceStats(workspaceStats: WorkspaceStats): string { + const output: string[] = []; + const lineLength = 60; + let col = 0; + + const appendAndWrap = (name: string, count: number) => { + const item = ` ${name}(${count})`; + + if (col + item.length > lineLength) { + output.push(line); + line = '| '; + col = line.length; + } + else { + col += item.length; + } + line += item; + }; + + // File Types + let line = '| File types:'; + const maxShown = 10; + let max = workspaceStats.fileTypes.length > maxShown ? maxShown : workspaceStats.fileTypes.length; + for (let i = 0; i < max; i++) { + const item = workspaceStats.fileTypes[i]; + appendAndWrap(item.name, item.count); + } + output.push(line); + + // Conf Files + if (workspaceStats.configFiles.length >= 0) { + line = '| Conf files:'; + col = 0; + workspaceStats.configFiles.forEach((item) => { + appendAndWrap(item.name, item.count); + }); + output.push(line); + } + + if (workspaceStats.launchConfigFiles.length > 0) { + let line = '| Launch Configs:'; + workspaceStats.launchConfigFiles.forEach(each => { + const item = each.count > 1 ? ` ${each.name}(${each.count})` : ` ${each.name}`; + line += item; + }); + output.push(line); + } + return output.join('\n'); + } + + private expandGPUFeatures(gpuFeatures: any): string { + const longestFeatureName = Math.max(...Object.keys(gpuFeatures).map(feature => feature.length)); + // Make columns aligned by adding spaces after feature name + return Object.keys(gpuFeatures).map(feature => `${feature}: ${repeat(' ', longestFeatureName - feature.length)} ${gpuFeatures[feature]}`).join('\n '); + } + + private formatWorkspaceMetadata(info: IMainProcessInfo): Promise { + const output: string[] = []; + const workspaceStatPromises: Promise[] = []; + + info.windows.forEach(window => { + if (window.folderURIs.length === 0 || !!window.remoteAuthority) { + return; + } + + output.push(`| Window (${window.title})`); + + window.folderURIs.forEach(uriComponents => { + const folderUri = URI.revive(uriComponents); + if (folderUri.scheme === 'file') { + const folder = folderUri.fsPath; + workspaceStatPromises.push(collectWorkspaceStats(folder, ['node_modules', '.git']).then(stats => { + let countMessage = `${stats.fileCount} files`; + if (stats.maxFilesReached) { + countMessage = `more than ${countMessage}`; + } + output.push(`| Folder (${basename(folder)}): ${countMessage}`); + output.push(this.formatWorkspaceStats(stats)); + + }).catch(error => { + output.push(`| Error: Unable to collect workspace stats for folder ${folder} (${error.toString()})`); + })); + } else { + output.push(`| Folder (${folderUri.toString()}): Workspace stats not available.`); + } + }); + }); + + return Promise.all(workspaceStatPromises) + .then(_ => output.join('\n')) + .catch(e => `Unable to collect workspace stats: ${e}`); + } + + private formatProcessList(info: IMainProcessInfo, rootProcess: ProcessItem): string { + const mapPidToWindowTitle = new Map(); + info.windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title)); + + const output: string[] = []; + + output.push('CPU %\tMem MB\t PID\tProcess'); + + if (rootProcess) { + this.formatProcessItem(info.mainPID, mapPidToWindowTitle, output, rootProcess, 0); + } + + return output.join('\n'); + } + + private formatProcessItem(mainPid: number, mapPidToWindowTitle: Map, output: string[], item: ProcessItem, indent: number): void { + const isRoot = (indent === 0); + + const MB = 1024 * 1024; + + // Format name with indent + let name: string; + if (isRoot) { + name = item.pid === mainPid ? `${product.applicationName} main` : 'remote agent'; + } else { + name = `${repeat(' ', indent)} ${item.name}`; + + if (item.name === 'window') { + name = `${name} (${mapPidToWindowTitle.get(item.pid)})`; + } + } + const memory = process.platform === 'win32' ? item.mem : (osLib.totalmem() * (item.mem / 100)); + output.push(`${pad(Number(item.load.toFixed(0)), 5, ' ')}\t${pad(Number((memory / MB).toFixed(0)), 6, ' ')}\t${pad(Number((item.pid).toFixed(0)), 6, ' ')}\t${name}`); + + // Recurse into children if any + if (Array.isArray(item.children)) { + item.children.forEach(child => this.formatProcessItem(mainPid, mapPidToWindowTitle, output, child, indent + 1)); + } + } + + public async reportWorkspaceStats(workspace: IWorkspace): Promise { + workspace.folders.forEach(folder => { + const folderUri = URI.revive(folder.uri); + if (folderUri.scheme === 'file') { + const folder = folderUri.fsPath; + collectWorkspaceStats(folder, ['node_modules', '.git']).then(stats => { + /* __GDPR__ + "workspace.metadata" : { + "fileTypes" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "configTypes" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "launchConfigs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } + } + */ + this.telemetryService.publicLog('workspace.metadata', { + fileTypes: stats.fileTypes, + configTypes: stats.configFiles, + launchConfigs: stats.launchConfigFiles + }); + }).catch(_ => { + // Report nothing if collecting metadata fails. + }); + } + }); + } } \ No newline at end of file diff --git a/src/vs/platform/issue/electron-main/issueService.ts b/src/vs/platform/issue/electron-main/issueService.ts index b794f8ffc8ade..5fc1f5464f1b4 100644 --- a/src/vs/platform/issue/electron-main/issueService.ts +++ b/src/vs/platform/issue/electron-main/issueService.ts @@ -9,14 +9,13 @@ import { parseArgs } from 'vs/platform/environment/node/argv'; import { IIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/common/issue'; import { BrowserWindow, ipcMain, screen, Event, dialog } from 'electron'; import { ILaunchService } from 'vs/platform/launch/electron-main/launchService'; -import { PerformanceInfo, IDiagnosticsService } from 'vs/platform/diagnostics/electron-main/diagnosticsService'; +import { PerformanceInfo, IDiagnosticsService, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { isMacintosh, IProcessEnvironment } from 'vs/base/common/platform'; import { ILogService } from 'vs/platform/log/common/log'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { IWindowState } from 'vs/platform/windows/electron-main/windows'; import { listProcesses } from 'vs/base/node/ps'; -import { isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; const DEFAULT_BACKGROUND_COLOR = '#1E1E1E'; @@ -40,10 +39,14 @@ export class IssueService implements IIssueService { } private registerListeners(): void { - ipcMain.on('vscode:issueSystemInfoRequest', (event: Event) => { - this.diagnosticsService.getSystemInfo(this.launchService).then(msg => { - event.sender.send('vscode:issueSystemInfoResponse', msg); - }); + ipcMain.on('vscode:issueSystemInfoRequest', async (event: Event) => { + Promise.all([this.launchService.getMainProcessInfo(), this.launchService.getRemoteDiagnostics({ includeProcesses: false, includeWorkspaceMetadata: false })]) + .then(result => { + const [info, remoteData] = result; + this.diagnosticsService.getSystemInfo(info, remoteData).then(msg => { + event.sender.send('vscode:issueSystemInfoResponse', msg); + }); + }); }); ipcMain.on('vscode:listProcesses', async (event: Event) => { @@ -262,8 +265,12 @@ export class IssueService implements IIssueService { }); } - public getSystemStatus(): Promise { - return this.diagnosticsService.getDiagnostics(this.launchService); + public async getSystemStatus(): Promise { + return Promise.all([this.launchService.getMainProcessInfo(), this.launchService.getRemoteDiagnostics({ includeProcesses: false, includeWorkspaceMetadata: false })]) + .then(result => { + const [info, remoteData] = result; + return this.diagnosticsService.getDiagnostics(info, remoteData); + }); } private getWindowPosition(parentWindow: BrowserWindow, defaultWidth: number, defaultHeight: number): IWindowState { @@ -335,14 +342,18 @@ export class IssueService implements IIssueService { } private getPerformanceInfo(): Promise { - return new Promise((resolve, reject) => { - this.diagnosticsService.getPerformanceInfo(this.launchService) - .then(diagnosticInfo => { - resolve(diagnosticInfo); - }) - .catch(err => { - this.logService.warn('issueService#getPerformanceInfo ', err.message); - reject(err); + return new Promise(async (resolve, reject) => { + Promise.all([this.launchService.getMainProcessInfo(), this.launchService.getRemoteDiagnostics({ includeProcesses: true, includeWorkspaceMetadata: true })]) + .then(result => { + const [info, remoteData] = result; + this.diagnosticsService.getPerformanceInfo(info, remoteData) + .then(diagnosticInfo => { + resolve(diagnosticInfo); + }) + .catch(err => { + this.logService.warn('issueService#getPerformanceInfo ', err.message); + reject(err); + }); }); }); } diff --git a/src/vs/platform/launch/common/launchService.ts b/src/vs/platform/launch/common/launchService.ts new file mode 100644 index 0000000000000..0c0e1db213499 --- /dev/null +++ b/src/vs/platform/launch/common/launchService.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. + *--------------------------------------------------------------------------------------------*/ +import { UriComponents } from 'vs/base/common/uri'; + +export interface IWindowInfo { + pid: number; + title: string; + folderURIs: UriComponents[]; + remoteAuthority?: string; +} + +export interface IMainProcessInfo { + mainPID: number; + // All arguments after argv[0], the exec path + mainArguments: string[]; + windows: IWindowInfo[]; + screenReader: boolean; + gpuFeatureStatus: any; +} \ No newline at end of file diff --git a/src/vs/platform/launch/electron-main/launchService.ts b/src/vs/platform/launch/electron-main/launchService.ts index d5d81a70bf88b..c192151f91535 100644 --- a/src/vs/platform/launch/electron-main/launchService.ts +++ b/src/vs/platform/launch/electron-main/launchService.ts @@ -14,12 +14,13 @@ import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-m import { whenDeleted } from 'vs/base/node/pfs'; import { IWorkspacesMainService } from 'vs/platform/workspaces/common/workspaces'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { URI, UriComponents } from 'vs/base/common/uri'; -import { BrowserWindow, ipcMain, Event as IpcEvent } from 'electron'; +import { URI } from 'vs/base/common/uri'; +import { BrowserWindow, ipcMain, Event as IpcEvent, app } from 'electron'; import { Event } from 'vs/base/common/event'; import { hasArgs } from 'vs/platform/environment/node/argv'; import { coalesce } from 'vs/base/common/arrays'; import { IDiagnosticInfoOptions, IDiagnosticInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnosticsService'; +import { IMainProcessInfo, IWindowInfo } from 'vs/platform/launch/common/launchService'; export const ID = 'launchService'; export const ILaunchService = createDecorator(ID); @@ -29,20 +30,6 @@ export interface IStartArguments { userEnv: IProcessEnvironment; } -export interface IWindowInfo { - pid: number; - title: string; - folderURIs: UriComponents[]; - remoteAuthority?: string; -} - -export interface IMainProcessInfo { - mainPID: number; - // All arguments after argv[0], the exec path - mainArguments: string[]; - windows: IWindowInfo[]; -} - export interface IRemoteDiagnosticOptions { includeProcesses?: boolean; includeWorkspaceMetadata?: boolean; @@ -280,7 +267,9 @@ export class LaunchService implements ILaunchService { return Promise.resolve({ mainPID: process.pid, mainArguments: process.argv.slice(1), - windows + windows, + screenReader: app.isAccessibilitySupportEnabled(), + gpuFeatureStatus: app.getGPUFeatureStatus() }); } diff --git a/src/vs/workbench/contrib/experiments/node/experimentService.ts b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts similarity index 99% rename from src/vs/workbench/contrib/experiments/node/experimentService.ts rename to src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts index b20c247e95aa7..3a451dc20bd88 100644 --- a/src/vs/workbench/contrib/experiments/node/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts @@ -19,7 +19,7 @@ import { match } from 'vs/base/common/glob'; import { asJson } from 'vs/base/node/request'; import { Emitter, Event } from 'vs/base/common/event'; import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/common/textfiles'; -import { WorkspaceStats } from 'vs/workbench/contrib/stats/node/workspaceStats'; +import { WorkspaceStats } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; import { CancellationToken } from 'vs/base/common/cancellation'; import { distinct } from 'vs/base/common/arrays'; import { lastSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties'; diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts b/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts index 29d91beb05ea7..3581351f6e080 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts @@ -5,7 +5,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { INotificationService, Severity, IPromptChoice } from 'vs/platform/notification/common/notification'; -import { IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties, IExperimentActionPromptCommand, ExperimentState } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties, IExperimentActionPromptCommand, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionsViewlet } from 'vs/workbench/contrib/extensions/common/extensions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts b/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts index b11ad64d0ce30..f3dcaf5074e21 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExperimentService, ExperimentService } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts index 69f2ac4cc51c9..d98057ee11190 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { ExperimentService, ExperimentActionType, ExperimentState, IExperiment } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { ExperimentService, ExperimentActionType, ExperimentState, IExperiment } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts index 16bfb42561397..bd21a63a6a264 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts @@ -13,7 +13,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { ExperimentalPrompts } from 'vs/workbench/contrib/experiments/electron-browser/experimentalPrompt'; -import { ExperimentActionType, ExperimentState, IExperiment, IExperimentActionPromptProperties, IExperimentService } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { ExperimentActionType, ExperimentState, IExperiment, IExperimentActionPromptProperties, IExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { TestExperimentService } from 'vs/workbench/contrib/experiments/test/electron-browser/experimentService.test'; import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index e16509f850df1..efa09426215b2 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -31,7 +31,7 @@ import { flatten, distinct, shuffle, coalesce } from 'vs/base/common/arrays'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { getHashedRemotesFromUri } from 'vs/workbench/contrib/stats/node/workspaceStats'; +import { getHashedRemotesFromUri } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; import { IRequestService } from 'vs/platform/request/node/request'; import { asJson } from 'vs/base/node/request'; import { isNumber } from 'vs/base/common/types'; @@ -41,7 +41,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { assign } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { extname } from 'vs/base/common/resources'; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts index e5f177c88b127..4b3f428cedee1 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts @@ -34,7 +34,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/ import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { distinct, coalesce } from 'vs/base/common/arrays'; -import { IExperimentService, IExperiment, ExperimentActionType } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, IExperiment, ExperimentActionType } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { alert } from 'vs/base/browser/ui/aria/aria'; import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list'; import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts index 32d569b0b57ea..90b0616f42132 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -41,7 +41,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { INotificationService, Severity, IPromptChoice, IPromptOptions } from 'vs/platform/notification/common/notification'; import { URLService } from 'vs/platform/url/common/urlService'; -import { IExperimentService } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { TestExperimentService } from 'vs/workbench/contrib/experiments/test/electron-browser/experimentService.test'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index 1425d24366c04..2f80ab3c8bf8f 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -34,7 +34,7 @@ import { URLService } from 'vs/platform/url/common/urlService'; import { URI } from 'vs/base/common/uri'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { SinonStub } from 'sinon'; -import { IExperimentService, ExperimentService, ExperimentState, ExperimentActionType } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, ExperimentService, ExperimentState, ExperimentActionType } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/stats/node/stats.contribution.ts b/src/vs/workbench/contrib/stats/electron-browser/stats.contribution.ts similarity index 89% rename from src/vs/workbench/contrib/stats/node/stats.contribution.ts rename to src/vs/workbench/contrib/stats/electron-browser/stats.contribution.ts index ee3b9b175d5b2..b2db16dac1c3d 100644 --- a/src/vs/workbench/contrib/stats/node/stats.contribution.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/stats.contribution.ts @@ -5,7 +5,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { WorkspaceStats } from 'vs/workbench/contrib/stats/node/workspaceStats'; +import { WorkspaceStats } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; // Register Workspace Stats Contribution diff --git a/src/vs/workbench/contrib/stats/node/workspaceStats.ts b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts similarity index 98% rename from src/vs/workbench/contrib/stats/node/workspaceStats.ts rename to src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts index db4fcadd84a9c..8504522b3ef18 100644 --- a/src/vs/workbench/contrib/stats/node/workspaceStats.ts +++ b/src/vs/workbench/contrib/stats/electron-browser/workspaceStats.ts @@ -21,6 +21,7 @@ import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/commo import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { joinPath } from 'vs/base/common/resources'; import { ITextFileService, ITextFileContent } from 'vs/workbench/services/textfile/common/textfiles'; +import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; const SshProtocolMatcher = /^([^@:]+@)?([^:]+):/; const SshUrlMatcher = /^([^@:]+@)?([^:]+):(.+)$/; @@ -224,7 +225,8 @@ export class WorkspaceStats implements IWorkbenchContribution { @INotificationService private readonly notificationService: INotificationService, @IQuickInputService private readonly quickInputService: IQuickInputService, @IStorageService private readonly storageService: IStorageService, - @ITextFileService private readonly textFileService: ITextFileService + @ITextFileService private readonly textFileService: ITextFileService, + @ISharedProcessService private readonly sharedProcessService: ISharedProcessService ) { this.report(); } @@ -239,6 +241,9 @@ export class WorkspaceStats implements IWorkbenchContribution { this.reportCloudStats(); this.reportProxyStats(); + + const diagnosticsChannel = this.sharedProcessService.getChannel('diagnostics'); + diagnosticsChannel.call('reportWorkspaceStats', this.contextService.getWorkspace()); } private static searchArray(arr: string[], regEx: RegExp): boolean | undefined { diff --git a/src/vs/workbench/contrib/stats/test/workspaceStats.test.ts b/src/vs/workbench/contrib/stats/test/workspaceStats.test.ts index 3543931c185c3..3cb2162ecdb97 100644 --- a/src/vs/workbench/contrib/stats/test/workspaceStats.test.ts +++ b/src/vs/workbench/contrib/stats/test/workspaceStats.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as crypto from 'crypto'; -import { getDomainsOfRemotes, getRemotes, getHashedRemotesFromConfig } from 'vs/workbench/contrib/stats/node/workspaceStats'; +import { getDomainsOfRemotes, getRemotes, getHashedRemotesFromConfig } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; function hash(value: string): string { return crypto.createHash('sha1').update(value.toString()).digest('hex'); diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts index 2c31578abdca4..67edffb9c5f76 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts @@ -13,7 +13,7 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; -import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/node/experimentService'; +import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { language, locale } from 'vs/base/common/platform'; import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index b1130436d6dbb..1175acef2f52b 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -215,7 +215,7 @@ import 'vs/workbench/contrib/files/browser/files.contribution'; import 'vs/workbench/contrib/backup/common/backup.contribution'; // Stats -import 'vs/workbench/contrib/stats/node/stats.contribution'; +import 'vs/workbench/contrib/stats/electron-browser/stats.contribution'; // Rapid Render Splash import 'vs/workbench/contrib/splash/electron-browser/partsSplash.contribution'; From 6f37438d9da9dc513aba006b6abda0782a6520bf Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 21 Jun 2019 17:46:21 -0700 Subject: [PATCH 296/364] Make return undefined explicit --- src/vs/workbench/contrib/webview/common/portMapping.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/common/portMapping.ts b/src/vs/workbench/contrib/webview/common/portMapping.ts index 487ee92148e98..964c0ac6da057 100644 --- a/src/vs/workbench/contrib/webview/common/portMapping.ts +++ b/src/vs/workbench/contrib/webview/common/portMapping.ts @@ -39,8 +39,9 @@ export class WebviewPortMappingManager extends Disposable { const uri = URI.parse(url); const requestLocalHostInfo = extractLocalHostUriMetaDataForPortMapping(uri); if (!requestLocalHostInfo) { - return requestLocalHostInfo; + return undefined; } + for (const mapping of this.mappings()) { if (mapping.webviewPort === requestLocalHostInfo.port) { if (this.extensionLocation && this.extensionLocation.scheme === REMOTE_HOST_SCHEME) { From 8455bc9eb67bc789ef6697e4d0d06392d6fe86d8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 10:42:20 -0700 Subject: [PATCH 297/364] Add missing return --- src/vs/workbench/contrib/webview/browser/pre/host.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/host.js b/src/vs/workbench/contrib/webview/browser/pre/host.js index 903bf54e1c780..6dd66c5b642da 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/host.js +++ b/src/vs/workbench/contrib/webview/browser/pre/host.js @@ -37,7 +37,7 @@ const workerReady = new Promise(async (resolveWorkerReady) => { if (!navigator.serviceWorker) { - resolveWorkerReady(); + return resolveWorkerReady(); } const expectedWorkerVersion = 1; From a8fd4499abf1eb85d8fc10e1de63e27f2a89a01a Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 10:46:24 -0700 Subject: [PATCH 298/364] Use explicit window.createWebviewManager --- src/vs/workbench/contrib/webview/browser/pre/host.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/host.js b/src/vs/workbench/contrib/webview/browser/pre/host.js index 6dd66c5b642da..3ffd33bdb72a1 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/host.js +++ b/src/vs/workbench/contrib/webview/browser/pre/host.js @@ -80,8 +80,8 @@ } }); }); - var createWebviewManager; - createWebviewManager({ + + window.createWebviewManager({ postMessage: hostMessaging.postMessage.bind(hostMessaging), onMessage: hostMessaging.onMessage.bind(hostMessaging), ready: workerReady, From 0dd15c5120128c4fb6f1d0eea70c419e32ba7098 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 24 Jun 2019 09:50:25 -0700 Subject: [PATCH 299/364] gdpr comments --- src/vs/workbench/services/keybinding/common/keymapInfo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index cc1108c5ca4a8..d0ff2d404694c 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -79,7 +79,7 @@ export interface ILinuxKeyboardLayoutInfo { /* __GDPR__FRAGMENT__ "IKeyboardLayoutInfo" : { "id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "lang": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + "lang": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, "localizedName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ From 41b3cbc1dc6b9e69a740c044bcd890294383369c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 24 Jun 2019 10:41:31 -0700 Subject: [PATCH 300/364] webkit fullscreen detection --- src/vs/base/browser/dom.ts | 1 + src/vs/workbench/browser/web.simpleservices.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 3fb6d8b35fcea..e201902ae248f 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -858,6 +858,7 @@ export const EventType = { RESIZE: 'resize', SCROLL: 'scroll', FULLSCREEN_CHANGE: 'fullscreenchange', + WK_FULLSCREEN_CHANGE: 'webkitfullscreenchange', // Form SELECT: 'select', CHANGE: 'change', diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index f5bccc1b42d04..193cb07fd319e 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -760,6 +760,14 @@ export class SimpleWindowService extends Disposable implements IWindowService { browser.setFullscreen(false); } })); + + this._register(addDisposableListener(document, EventType.WK_FULLSCREEN_CHANGE, () => { + if (document.fullscreenElement || (document).webkitFullscreenElement || (document).webkitIsFullScreen) { + browser.setFullscreen(true); + } else { + browser.setFullscreen(false); + } + })); } isFocused(): Promise { @@ -832,10 +840,8 @@ export class SimpleWindowService extends Disposable implements IWindowService { try { if (!(document).webkitIsFullScreen) { (target).webkitRequestFullscreen(); // it's async, but doesn't return a real promise. - browser.setFullscreen(true); // we have to set this proactively because Safari doesn't emit fullscreenchange event. } else { (document).webkitExitFullscreen(); // it's async, but doesn't return a real promise. - browser.setFullscreen(false); } } catch { console.warn('Enter/Exit Full Screen failed'); From 777010a73437c92b599e27f25d703703b91017e7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 11:54:34 -0700 Subject: [PATCH 301/364] Fix file name spelling --- .../src/tsServer/{spanwer.ts => spawner.ts} | 0 .../typescript-language-features/src/typescriptServiceClient.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename extensions/typescript-language-features/src/tsServer/{spanwer.ts => spawner.ts} (100%) diff --git a/extensions/typescript-language-features/src/tsServer/spanwer.ts b/extensions/typescript-language-features/src/tsServer/spawner.ts similarity index 100% rename from extensions/typescript-language-features/src/tsServer/spanwer.ts rename to extensions/typescript-language-features/src/tsServer/spawner.ts diff --git a/extensions/typescript-language-features/src/typescriptServiceClient.ts b/extensions/typescript-language-features/src/typescriptServiceClient.ts index 6285981756ac8..996478d6c22b6 100644 --- a/extensions/typescript-language-features/src/typescriptServiceClient.ts +++ b/extensions/typescript-language-features/src/typescriptServiceClient.ts @@ -25,7 +25,7 @@ import Tracer from './utils/tracer'; import { inferredProjectConfig } from './utils/tsconfig'; import { TypeScriptVersionPicker } from './utils/versionPicker'; import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider'; -import { TypeScriptServerSpawner } from './tsServer/spanwer'; +import { TypeScriptServerSpawner } from './tsServer/spawner'; const localize = nls.loadMessageBundle(); From 89012792f805ad61a64bcf272cca6e8dd9a509cf Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 24 Jun 2019 12:00:13 -0700 Subject: [PATCH 302/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7755b30ebef3c..e7c10b4b0a7e7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "6e5b8dfbbda7ce121811e397d16842251bd666aa", + "distro": "f22db93b3c64b0787d98aef556519af82c64860b", "author": { "name": "Microsoft Corporation" }, From a36931eb31deee60e1cc051c0396db0a8ce75620 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 24 Jun 2019 20:40:14 +0200 Subject: [PATCH 303/364] add logging --- .../extensionManagement/node/extensionManagementIpc.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts index f66cde1d510d9..e290cc0b0694c 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts @@ -12,6 +12,7 @@ import { cloneAndChange } from 'vs/base/common/objects'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ILogService } from 'vs/platform/log/common/log'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI { return URI.revive(transformer ? transformer.transformIncoming(uri) : uri); @@ -110,11 +111,14 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer } catch (error) { if (this.remote) { try { + this.logService.error(`Error while installing '${extension.identifier.id}' extension in the remote server.`, toErrorMessage(error)); + this.logService.info(`Trying to download '${extension.identifier.id}' extension locally and install`); const compatible = await this.galleryService.getCompatibleExtension(extension); if (compatible) { const installed = await this.getInstalled(ExtensionType.User); const location = await this.galleryService.download(compatible, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); await this.install(URI.file(location)); + this.logService.info(`Successfully installed '${extension.identifier.id}' extension`); return; } } catch (e) { From ba398b6ddde91284c1c1ecb8f4a6f6503cbedc44 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 24 Jun 2019 20:40:32 +0200 Subject: [PATCH 304/364] disabling installing extension from gallery when not enabled --- .../extensionManagement/node/extensionManagementService.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 36fc28f7e0069..082fea1589a53 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -265,6 +265,9 @@ export class ExtensionManagementService extends Disposable implements IExtension } async installFromGallery(extension: IGalleryExtension): Promise { + if (!this.galleryService.isEnabled()) { + return Promise.reject(new Error(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled"))); + } const startTime = new Date().getTime(); const onDidInstallExtensionSuccess = (extension: IGalleryExtension, operation: InstallOperation, local: ILocalExtension) => { From 4f6c6c7f81bf6793f1b7841bf70495961a96781c Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 24 Jun 2019 13:14:40 -0700 Subject: [PATCH 305/364] status.workbench.keyboardLayout --- .../contrib/preferences/browser/keyboardLayoutPicker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index ddab5c033e450..043e3dd6e2a48 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -41,8 +41,8 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), command: KEYBOARD_LAYOUT_OPEN_PICKER }, - 'status.editor.screenReaderMode', - nls.localize('status.editor.screenReaderMode', "Screen Reader Mode"), + 'status.workbench.keyboardLayout', + nls.localize('status.workbench.keyboardLayout', "Current keyboard layout"), StatusbarAlignment.RIGHT ); } From e899b1c6b1ead0ffaf9af31cd5af8e09e5c390d1 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Mon, 24 Jun 2019 13:37:10 -0700 Subject: [PATCH 306/364] Move Inspect Keyboard Layout JSON to workbench --- .../codeEditor/browser/inspectKeybindings.ts | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts b/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts index 8c7aaaf0e3350..ec27d6a2e2282 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts @@ -9,6 +9,10 @@ import { EditorAction, ServicesAccessor, registerEditorAction } from 'vs/editor/ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IUntitledResourceInput } from 'vs/workbench/common/editor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { Action } from 'vs/base/common/actions'; class InspectKeyMap extends EditorAction { @@ -31,23 +35,23 @@ class InspectKeyMap extends EditorAction { registerEditorAction(InspectKeyMap); -class InspectKeyMapJSON extends EditorAction { - - constructor() { - super({ - id: 'workbench.action.inspectKeyMappingsJSON', - label: nls.localize('workbench.action.inspectKeyMapJSON', "Developer: Inspect Key Mappings (JSON)"), - alias: 'Developer: Inspect Key Mappings (JSON)', - precondition: undefined - }); +class InspectKeyMapJSON extends Action { + public static readonly ID = 'workbench.action.inspectKeyMappingsJSON'; + public static readonly LABEL = nls.localize('workbench.action.inspectKeyMapJSON', "Developer: Inspect Key Mappings (JSON)"); + + constructor( + id: string, + label: string, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IEditorService private readonly _editorService: IEditorService + ) { + super(id, label); } - public run(accessor: ServicesAccessor, editor: ICodeEditor): void { - const keybindingService = accessor.get(IKeybindingService); - const editorService = accessor.get(IEditorService); - - editorService.openEditor({ contents: keybindingService._dumpDebugInfoJSON(), options: { pinned: true } } as IUntitledResourceInput); + public run(): Promise { + return this._editorService.openEditor({ contents: this._keybindingService._dumpDebugInfoJSON(), options: { pinned: true } } as IUntitledResourceInput); } } -registerEditorAction(InspectKeyMapJSON); +const registry = Registry.as(ActionExtensions.WorkbenchActions); +registry.registerWorkbenchAction(new SyncActionDescriptor(InspectKeyMapJSON, InspectKeyMapJSON.ID, InspectKeyMapJSON.LABEL), 'Developer: Inspect Key Mappings (JSON)'); From 397629a1ad9482367990dffe99a26106495f5e8e Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 24 Jun 2019 22:29:13 +0200 Subject: [PATCH 307/364] return local extension after install --- .../common/extensionManagement.ts | 4 ++-- .../node/extensionManagementIpc.ts | 13 +++++++------ .../node/extensionManagementService.ts | 14 +++++++------- src/vs/workbench/browser/web.simpleservices.ts | 10 ++++++---- .../extensions/node/extensionsWorkbenchService.ts | 6 +++--- .../extensions/node/multiExtensionManagement.ts | 10 +++++----- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 8b024db44b215..833fedd1fccac 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -196,8 +196,8 @@ export interface IExtensionManagementService { zip(extension: ILocalExtension): Promise; unzip(zipLocation: URI, type: ExtensionType): Promise; - install(vsix: URI): Promise; - installFromGallery(extension: IGalleryExtension): Promise; + install(vsix: URI): Promise; + installFromGallery(extension: IGalleryExtension): Promise; uninstall(extension: ILocalExtension, force?: boolean): Promise; reinstallFromGallery(extension: ILocalExtension): Promise; getInstalled(type?: ExtensionType): Promise; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts index e290cc0b0694c..9e49db285ccca 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts @@ -101,13 +101,14 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer return Promise.resolve(this.channel.call('unzip', [zipLocation, type])); } - install(vsix: URI): Promise { - return Promise.resolve(this.channel.call('install', [vsix])); + install(vsix: URI): Promise { + return Promise.resolve(this.channel.call('install', [vsix])).then(local => transformIncomingExtension(local, null)); } - async installFromGallery(extension: IGalleryExtension): Promise { + async installFromGallery(extension: IGalleryExtension): Promise { try { - await Promise.resolve(this.channel.call('installFromGallery', [extension])); + const local = await Promise.resolve(this.channel.call('installFromGallery', [extension])); + return transformIncomingExtension(local, null); } catch (error) { if (this.remote) { try { @@ -117,9 +118,9 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer if (compatible) { const installed = await this.getInstalled(ExtensionType.User); const location = await this.galleryService.download(compatible, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); - await this.install(URI.file(location)); + const local = await this.install(URI.file(location)); this.logService.info(`Successfully installed '${extension.identifier.id}' extension`); - return; + return local; } } catch (e) { this.logService.error(e); diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 082fea1589a53..90b0c0f7bce28 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -109,7 +109,7 @@ export class ExtensionManagementService extends Disposable implements IExtension private uninstalledFileLimiter: Queue; private reportedExtensions: Promise | undefined; private lastReportTimestamp = 0; - private readonly installingExtensions: Map> = new Map>(); + private readonly installingExtensions: Map> = new Map>(); private readonly uninstallingExtensions: Map> = new Map>(); private readonly manifestCache: ExtensionsManifestCache; private readonly extensionLifecycle: ExtensionsLifecycle; @@ -158,7 +158,7 @@ export class ExtensionManagementService extends Disposable implements IExtension unzip(zipLocation: URI, type: ExtensionType): Promise { this.logService.trace('ExtensionManagementService#unzip', zipLocation.toString()); - return this.install(zipLocation, type); + return this.install(zipLocation, type).then(local => local.identifier); } private collectFiles(extension: ILocalExtension): Promise { @@ -187,7 +187,7 @@ export class ExtensionManagementService extends Disposable implements IExtension } - install(vsix: URI, type: ExtensionType = ExtensionType.User): Promise { + install(vsix: URI, type: ExtensionType = ExtensionType.User): Promise { this.logService.trace('ExtensionManagementService#install', vsix.toString()); return createCancelablePromise(token => { return this.downloadVsix(vsix).then(downloadLocation => { @@ -222,7 +222,7 @@ export class ExtensionManagementService extends Disposable implements IExtension metadata => this.installFromZipPath(identifierWithVersion, zipPath, metadata, type, operation, token), () => this.installFromZipPath(identifierWithVersion, zipPath, null, type, operation, token)) .then( - () => { this.logService.info('Successfully installed the extension:', identifier.id); return identifier; }, + local => { this.logService.info('Successfully installed the extension:', identifier.id); return local; }, e => { this.logService.error('Failed to install the extension:', identifier.id, e.message); return Promise.reject(e); @@ -264,7 +264,7 @@ export class ExtensionManagementService extends Disposable implements IExtension )); } - async installFromGallery(extension: IGalleryExtension): Promise { + async installFromGallery(extension: IGalleryExtension): Promise { if (!this.galleryService.isEnabled()) { return Promise.reject(new Error(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled"))); } @@ -301,7 +301,7 @@ export class ExtensionManagementService extends Disposable implements IExtension this._onInstallExtension.fire({ identifier: extension.identifier, gallery: extension }); let operation: InstallOperation = InstallOperation.Install; - let cancellationToken: CancellationToken, successCallback: (a?: any) => void, errorCallback: (e?: any) => any | null; + let cancellationToken: CancellationToken, successCallback: (local: ILocalExtension) => void, errorCallback: (e?: any) => any | null; cancellablePromise = createCancelablePromise(token => { cancellationToken = token; return new Promise((c, e) => { successCallback = c; errorCallback = e; }); }); this.installingExtensions.set(key, cancellablePromise); try { @@ -323,7 +323,7 @@ export class ExtensionManagementService extends Disposable implements IExtension } this.installingExtensions.delete(key); onDidInstallExtensionSuccess(extension, operation, local); - successCallback(null); + successCallback(local); }, error => { this.installingExtensions.delete(key); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 193cb07fd319e..17851c2499490 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -401,12 +401,13 @@ export class SimpleExtensionManagementService implements IExtensionManagementSer return Promise.resolve(undefined); } - install(vsix: URI): Promise { + install(vsix: URI): Promise { // @ts-ignore return Promise.resolve(undefined); } - installFromGallery(extension: IGalleryExtension): Promise { + installFromGallery(extension: IGalleryExtension): Promise { + // @ts-ignore return Promise.resolve(undefined); } @@ -488,12 +489,13 @@ export class SimpleMultiExtensionsManagementService implements IExtensionManagem return Promise.resolve(undefined); } - install(vsix: URI): Promise { + install(vsix: URI): Promise { // @ts-ignore return Promise.resolve(undefined); } - installFromGallery(extension: IGalleryExtension): Promise { + installFromGallery(extension: IGalleryExtension): Promise { + // @ts-ignore return Promise.resolve(undefined); } diff --git a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts index 64eac307ad393..d91ddb528821f 100644 --- a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts @@ -761,9 +761,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension install(extension: string | IExtension): Promise { if (typeof extension === 'string') { return this.installWithProgress(async () => { - const extensionIdentifier = await this.extensionService.install(URI.file(extension)); - this.checkAndEnableDisabledDependencies(extensionIdentifier); - return this.local.filter(local => areSameExtensions(local.identifier, extensionIdentifier))[0]; + const { identifier } = await this.extensionService.install(URI.file(extension)); + this.checkAndEnableDisabledDependencies(identifier); + return this.local.filter(local => areSameExtensions(local.identifier, identifier))[0]; }); } diff --git a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts index e27a2a7ed4601..1425161d0d73e 100644 --- a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts +++ b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts @@ -134,13 +134,13 @@ export class MultiExtensionManagementService extends Disposable implements IExte return Promise.all(this.servers.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation, type))).then(([extensionIdentifier]) => extensionIdentifier); } - async install(vsix: URI): Promise { + async install(vsix: URI): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { const manifest = await getManifest(vsix.fsPath); if (isLanguagePackExtension(manifest)) { // Install on both servers - const [extensionIdentifier] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix))); - return extensionIdentifier; + const [local] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix))); + return local; } if (isUIExtension(manifest, this.productService, this.configurationService)) { // Install only on local server @@ -155,13 +155,13 @@ export class MultiExtensionManagementService extends Disposable implements IExte return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); } - async installFromGallery(gallery: IGalleryExtension): Promise { + async installFromGallery(gallery: IGalleryExtension): Promise { if (this.extensionManagementServerService.remoteExtensionManagementServer) { const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None); if (manifest) { if (isLanguagePackExtension(manifest)) { // Install on both servers - return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(() => undefined); + return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local); } if (isUIExtension(manifest, this.productService, this.configurationService)) { // Install only on local server From eb451dd57ab306b7eaea2cac2e06a79ab89911f4 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Mon, 24 Jun 2019 23:17:20 +0200 Subject: [PATCH 308/364] install deps and packs while installing from gallery --- .../node/extensionManagementIpc.ts | 33 +---- .../extensionsActions.test.ts | 3 +- .../electron-browser/extensionsViews.test.ts | 3 +- .../extensionManagementServerService.ts | 9 +- .../remoteExtensionManagementIpc.ts | 140 ++++++++++++++++++ .../node/multiExtensionManagement.ts | 64 +------- 6 files changed, 157 insertions(+), 95 deletions(-) create mode 100644 src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts diff --git a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts index 9e49db285ccca..b88350f44c714 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementIpc.ts @@ -4,15 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; -import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension, IExtensionGalleryService, InstallOperation } from '../common/extensionManagement'; +import { IExtensionManagementService, ILocalExtension, InstallExtensionEvent, DidInstallExtensionEvent, IGalleryExtension, DidUninstallExtensionEvent, IExtensionIdentifier, IGalleryMetadata, IReportedExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { Event } from 'vs/base/common/event'; import { URI, UriComponents } from 'vs/base/common/uri'; import { IURITransformer, DefaultURITransformer, transformAndReviveIncomingURIs } from 'vs/base/common/uriIpc'; import { cloneAndChange } from 'vs/base/common/objects'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; -import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { ILogService } from 'vs/platform/log/common/log'; -import { toErrorMessage } from 'vs/base/common/errorMessage'; function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI { return URI.revive(transformer ? transformer.transformIncoming(uri) : uri); @@ -83,9 +80,6 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer constructor( private readonly channel: IChannel, - private readonly remote: boolean, - private readonly galleryService: IExtensionGalleryService, - private readonly logService: ILogService ) { } get onInstallExtension(): Event { return this.channel.listen('onInstallExtension'); } @@ -105,29 +99,8 @@ export class ExtensionManagementChannelClient implements IExtensionManagementSer return Promise.resolve(this.channel.call('install', [vsix])).then(local => transformIncomingExtension(local, null)); } - async installFromGallery(extension: IGalleryExtension): Promise { - try { - const local = await Promise.resolve(this.channel.call('installFromGallery', [extension])); - return transformIncomingExtension(local, null); - } catch (error) { - if (this.remote) { - try { - this.logService.error(`Error while installing '${extension.identifier.id}' extension in the remote server.`, toErrorMessage(error)); - this.logService.info(`Trying to download '${extension.identifier.id}' extension locally and install`); - const compatible = await this.galleryService.getCompatibleExtension(extension); - if (compatible) { - const installed = await this.getInstalled(ExtensionType.User); - const location = await this.galleryService.download(compatible, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); - const local = await this.install(URI.file(location)); - this.logService.info(`Successfully installed '${extension.identifier.id}' extension`); - return local; - } - } catch (e) { - this.logService.error(e); - } - } - throw error; - } + installFromGallery(extension: IGalleryExtension): Promise { + return Promise.resolve(this.channel.call('installFromGallery', [extension])).then(local => transformIncomingExtension(local, null)); } uninstall(extension: ILocalExtension, force = false): Promise { diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 68f6b32c349c7..9d1919ae5e5f8 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -40,6 +40,7 @@ import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedPr import { CancellationToken } from 'vs/base/common/cancellation'; import { ILabelService } from 'vs/platform/label/common/label'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/electron-browser/extensionManagementServerService'; +import { IProductService } from 'vs/platform/product/common/product'; suite('ExtensionsActions Test', () => { @@ -78,7 +79,7 @@ suite('ExtensionsActions Test', () => { instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService { private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' }; constructor() { - super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(ILogService)); + super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IConfigurationService), instantiationService.get(IProductService), instantiationService.get(ILogService)); } get localExtensionManagementServer(): IExtensionManagementServer { return this._localExtensionManagementServer; } set localExtensionManagementServer(server: IExtensionManagementServer) { } diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index 2f80ab3c8bf8f..c9ad5d996c875 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -40,6 +40,7 @@ import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browse import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/electron-browser/extensionManagementServerService'; +import { IProductService } from 'vs/platform/product/common/product'; suite('ExtensionsListView Tests', () => { @@ -93,7 +94,7 @@ suite('ExtensionsListView Tests', () => { instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService { private _localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', authority: 'vscode-local' }; constructor() { - super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(ILogService)); + super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IConfigurationService), instantiationService.get(IProductService), instantiationService.get(ILogService)); } get localExtensionManagementServer(): IExtensionManagementServer { return this._localExtensionManagementServer; } set localExtensionManagementServer(server: IExtensionManagementServer) { } diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts index b574fa9d9af14..611ab9aec95e2 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionManagementServerService.ts @@ -14,6 +14,9 @@ import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; +import { RemoteExtensionManagementChannelClient } from 'vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IProductService } from 'vs/platform/product/common/product'; const localExtensionManagementServerAuthority: string = 'vscode-local'; @@ -28,14 +31,16 @@ export class ExtensionManagementServerService implements IExtensionManagementSer @ISharedProcessService sharedProcessService: ISharedProcessService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, @IExtensionGalleryService galleryService: IExtensionGalleryService, + @IConfigurationService configurationService: IConfigurationService, + @IProductService productService: IProductService, @ILogService logService: ILogService ) { - const localExtensionManagementService = new ExtensionManagementChannelClient(sharedProcessService.getChannel('extensions'), false, galleryService, logService); + const localExtensionManagementService = new ExtensionManagementChannelClient(sharedProcessService.getChannel('extensions')); this.localExtensionManagementServer = { extensionManagementService: localExtensionManagementService, authority: localExtensionManagementServerAuthority, label: localize('local', "Local") }; const remoteAgentConnection = remoteAgentService.getConnection(); if (remoteAgentConnection) { - const extensionManagementService = new ExtensionManagementChannelClient(remoteAgentConnection.getChannel('extensions'), true, galleryService, logService); + const extensionManagementService = new RemoteExtensionManagementChannelClient(remoteAgentConnection.getChannel('extensions'), this.localExtensionManagementServer.extensionManagementService, galleryService, logService, configurationService, productService); this.remoteExtensionManagementServer = { authority: remoteAgentConnection.remoteAuthority, extensionManagementService, label: localize('remote', "Remote") }; } } diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts new file mode 100644 index 0000000000000..0879eb39178ee --- /dev/null +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -0,0 +1,140 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IChannel } from 'vs/base/parts/ipc/common/ipc'; +import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { URI } from 'vs/base/common/uri'; +import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions'; +import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; +import { ILogService } from 'vs/platform/log/common/log'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; +import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; +import { isNonEmptyArray } from 'vs/base/common/arrays'; +import { values } from 'vs/base/common/map'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { localize } from 'vs/nls'; +import { IProductService } from 'vs/platform/product/common/product'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; + +export class RemoteExtensionManagementChannelClient extends ExtensionManagementChannelClient { + + _serviceBrand: any; + + constructor( + channel: IChannel, + private readonly localExtensionManagementService: IExtensionManagementService, + private readonly galleryService: IExtensionGalleryService, + private readonly logService: ILogService, + private readonly configurationService: IConfigurationService, + private readonly productService: IProductService + ) { + super(channel); + } + + async install(vsix: URI): Promise { + const local = await super.install(vsix); + await this.installUIDependenciesAndPackedExtensions(local); + return local; + } + + async installFromGallery(extension: IGalleryExtension): Promise { + const local = await this.doInstallFromGallery(extension); + await this.installUIDependenciesAndPackedExtensions(local); + return local; + } + + private async doInstallFromGallery(extension: IGalleryExtension): Promise { + try { + const local = await super.installFromGallery(extension); + return local; + } catch (error) { + try { + this.logService.error(`Error while installing '${extension.identifier.id}' extension in the remote server.`, toErrorMessage(error)); + this.logService.info(`Trying to download '${extension.identifier.id}' extension locally and install`); + const local = await this.downloadCompatibleAndInstall(extension); + this.logService.info(`Successfully installed '${extension.identifier.id}' extension`); + return local; + } catch (e) { + this.logService.error(e); + throw error; + } + } + } + + private async downloadCompatibleAndInstall(extension: IGalleryExtension): Promise { + const installed = await this.getInstalled(ExtensionType.User); + const compatible = await this.galleryService.getCompatibleExtension(extension); + if (!compatible) { + return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version))); + } + const local = await this.downloadAndInstall(extension, installed); + const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(local.manifest, CancellationToken.None); + await Promise.all(workspaceExtensions.map(e => this.downloadAndInstall(e, installed))); + return local; + } + + private async downloadAndInstall(extension: IGalleryExtension, installed: ILocalExtension[]): Promise { + const location = await this.galleryService.download(extension, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); + return super.install(URI.file(location)); + } + + private async installUIDependenciesAndPackedExtensions(local: ILocalExtension): Promise { + const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(local.manifest, CancellationToken.None); + const installed = await this.localExtensionManagementService.getInstalled(); + const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier))); + await Promise.all(toInstall.map(d => this.localExtensionManagementService.installFromGallery(d))); + } + + private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise { + const result = new Map(); + const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])]; + await this.getDependenciesAndPackedExtensionsRecursively(extensions, result, true, token); + return values(result); + } + + private async getAllWorkspaceDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise { + const result = new Map(); + const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])]; + await this.getDependenciesAndPackedExtensionsRecursively(extensions, result, false, token); + return values(result); + } + + private async getDependenciesAndPackedExtensionsRecursively(toGet: string[], result: Map, uiExtension: boolean, token: CancellationToken): Promise { + if (toGet.length === 0) { + return Promise.resolve(); + } + + const extensions = (await this.galleryService.query({ names: toGet, pageSize: toGet.length }, token)).firstPage; + const manifests = await Promise.all(extensions.map(e => this.galleryService.getManifest(e, token))); + const extensionsManifests: IExtensionManifest[] = []; + for (let idx = 0; idx < extensions.length; idx++) { + const extension = extensions[idx]; + const manifest = manifests[idx]; + if (manifest && isUIExtension(manifest, this.productService, this.configurationService) === uiExtension) { + result.set(extension.identifier.id.toLowerCase(), extension); + extensionsManifests.push(manifest); + } + } + toGet = []; + for (const extensionManifest of extensionsManifests) { + if (isNonEmptyArray(extensionManifest.extensionDependencies)) { + for (const id of extensionManifest.extensionDependencies) { + if (!result.has(id.toLowerCase())) { + toGet.push(id); + } + } + } + if (isNonEmptyArray(extensionManifest.extensionPack)) { + for (const id of extensionManifest.extensionPack) { + if (!result.has(id.toLowerCase())) { + toGet.push(id); + } + } + } + } + return this.getDependenciesAndPackedExtensionsRecursively(toGet, result, uiExtension, token); + } +} \ No newline at end of file diff --git a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts index 1425161d0d73e..1760b4d5fc30a 100644 --- a/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts +++ b/src/vs/workbench/services/extensions/node/multiExtensionManagement.ts @@ -8,7 +8,7 @@ import { IExtensionManagementService, ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata, IExtensionManagementServerService, IExtensionManagementServer, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { ExtensionType, IExtensionManifest, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; +import { ExtensionType, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; import { URI } from 'vs/base/common/uri'; import { Disposable } from 'vs/base/common/lifecycle'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -18,8 +18,6 @@ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extens import { localize } from 'vs/nls'; import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { isNonEmptyArray } from 'vs/base/common/arrays'; -import { values } from 'vs/base/common/map'; import { IProductService } from 'vs/platform/product/common/product'; export class MultiExtensionManagementService extends Disposable implements IExtensionManagementService { @@ -147,10 +145,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); } // Install only on remote server - const promise = this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix); - // Install UI Dependencies on local server - await this.installUIDependenciesAndPackedExtensions(manifest); - return promise; + return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix); } return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix); } @@ -168,10 +163,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery); } // Install only on remote server - const promise = this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery); - // Install UI dependencies and packed extensions on local server - await this.installUIDependenciesAndPackedExtensions(manifest); - return promise; + return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery); } else { return Promise.reject(localize('Manifest is not found', "Installing Extension {0} failed: Manifest is not found.", gallery.displayName || gallery.name)); } @@ -179,13 +171,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery); } - private async installUIDependenciesAndPackedExtensions(manifest: IExtensionManifest): Promise { - const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(manifest, CancellationToken.None); - const installed = await this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getInstalled(); - const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier))); - await Promise.all(toInstall.map(d => this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(d))); - } - getExtensionsReport(): Promise { return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getExtensionsReport(); } @@ -193,49 +178,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte private getServer(extension: ILocalExtension): IExtensionManagementServer | null { return this.extensionManagementServerService.getExtensionManagementServer(extension.location); } - - private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise { - const result = new Map(); - const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])]; - await this.getAllUIDependenciesAndPackedExtensionsRecursively(extensions, result, token); - return values(result); - } - - private async getAllUIDependenciesAndPackedExtensionsRecursively(toGet: string[], result: Map, token: CancellationToken): Promise { - if (toGet.length === 0) { - return Promise.resolve(); - } - - const extensions = (await this.extensionGalleryService.query({ names: toGet, pageSize: toGet.length }, token)).firstPage; - const manifests = await Promise.all(extensions.map(e => this.extensionGalleryService.getManifest(e, token))); - const uiExtensionsManifests: IExtensionManifest[] = []; - for (let idx = 0; idx < extensions.length; idx++) { - const extension = extensions[idx]; - const manifest = manifests[idx]; - if (manifest && isUIExtension(manifest, this.productService, this.configurationService)) { - result.set(extension.identifier.id.toLowerCase(), extension); - uiExtensionsManifests.push(manifest); - } - } - toGet = []; - for (const uiExtensionManifest of uiExtensionsManifests) { - if (isNonEmptyArray(uiExtensionManifest.extensionDependencies)) { - for (const id of uiExtensionManifest.extensionDependencies) { - if (!result.has(id.toLowerCase())) { - toGet.push(id); - } - } - } - if (isNonEmptyArray(uiExtensionManifest.extensionPack)) { - for (const id of uiExtensionManifest.extensionPack) { - if (!result.has(id.toLowerCase())) { - toGet.push(id); - } - } - } - } - return this.getAllUIDependenciesAndPackedExtensionsRecursively(toGet, result, token); - } } registerSingleton(IExtensionManagementService, MultiExtensionManagementService); \ No newline at end of file From 1bbd3e6659803c233dfac2a749ecd636ed0ddcfe Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 24 Jun 2019 14:22:22 -0700 Subject: [PATCH 309/364] Fix default shell selector outside of Windows Fixes #76040 --- .../contrib/terminal/common/terminalService.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 1f8e90b6407a5..58cca1cbc6ea5 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -17,7 +17,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IFileService } from 'vs/platform/files/common/files'; import { escapeNonWindowsPath } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; -import { isWindows } from 'vs/base/common/platform'; +import { isWindows, isMacintosh, OperatingSystem } from 'vs/base/common/platform'; import { basename } from 'vs/base/common/path'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { timeout } from 'vs/base/common/async'; @@ -549,7 +549,14 @@ export abstract class TerminalService implements ITerminalService { return undefined; } const shell = value.description; - await this._configurationService.updateValue('terminal.integrated.shell.windows', shell, ConfigurationTarget.USER).then(() => shell); + const env = await this._remoteAgentService.getEnvironment(); + let platformKey: string; + if (env) { + platformKey = env.os === OperatingSystem.Windows ? 'windows' : (OperatingSystem.Macintosh ? 'osx' : 'linux'); + } else { + platformKey = isWindows ? 'windows' : (isMacintosh ? 'osx' : 'linux'); + } + await this._configurationService.updateValue(`terminal.integrated.shell.${platformKey}`, shell, ConfigurationTarget.USER).then(() => shell); return Promise.resolve(); }); }); From 85ab838037b1283a1401a870bc79c3e3ca4cdcfe Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 15:19:03 -0700 Subject: [PATCH 310/364] Add explicit win32 gheck for using user specific temp folder --- extensions/typescript-language-features/src/utils/electron.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/utils/electron.ts b/extensions/typescript-language-features/src/utils/electron.ts index 1f542fe07cc66..ea16bae42773f 100644 --- a/extensions/typescript-language-features/src/utils/electron.ts +++ b/extensions/typescript-language-features/src/utils/electron.ts @@ -14,7 +14,7 @@ const getRootTempDir = (() => { let dir: string | undefined; return () => { if (!dir) { - dir = temp.getTempFile(`vscode-typescript${process.getuid ? process.getuid() : ''}`); + dir = temp.getTempFile(`vscode-typescript${process.platform !== 'win32' && process.getuid ? process.getuid() : ''}`); } if (!fs.existsSync(dir)) { fs.mkdirSync(dir); From 8ac732d11388f60938c421d26aa9aa123e81180f Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Mon, 24 Jun 2019 16:21:36 -0700 Subject: [PATCH 311/364] Always use settings UI when querying online services, fixes #75542 --- .../contrib/preferences/browser/preferences.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts index 20c9985f6322c..4f8fae9ac52e9 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts @@ -742,7 +742,7 @@ CommandsRegistry.registerCommand(SETTINGS_EDITOR_COMMAND_FILTER_ONLINE, serviceA if (control instanceof SettingsEditor2) { control.focusSearch(`@tag:usesOnlineServices`); } else { - serviceAccessor.get(IPreferencesService).openSettings(undefined, '@tag:usesOnlineServices'); + serviceAccessor.get(IPreferencesService).openSettings(false, '@tag:usesOnlineServices'); } }); From 10831237586049f51630d308eb4c85d488fa4f93 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 24 Jun 2019 16:51:11 -0700 Subject: [PATCH 312/364] Disable conpty in terminal when accessibility mode is on Fixes #76043 --- .../workbench/api/node/extHostTerminalService.ts | 1 + .../contrib/terminal/browser/terminalInstance.ts | 2 +- .../terminal/browser/terminalProcessManager.ts | 14 ++++++++++---- .../workbench/contrib/terminal/common/terminal.ts | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index d0d8920c25cf8..d7432604d4d97 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -538,6 +538,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { // Fork the process and listen for messages this._logService.debug(`Terminal process launching on ext host`, shellLaunchConfig, initialCwd, cols, rows, env); // TODO: Support conpty on remote, it doesn't seem to work for some reason? + // TODO: When conpty is enabled, only enable it when accessibilityMode is off const enableConpty = false; //terminalConfig.get('windowsEnableConpty') as boolean; const p = new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, enableConpty, this._logService); p.onProcessReady((e: { pid: number, cwd: string }) => this._proxy.$sendProcessReady(id, e.pid, e.cwd)); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 95c3afd044527..0c0f6721e9eda 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -970,7 +970,7 @@ export class TerminalInstance implements ITerminalInstance { // Create the process asynchronously to allow the terminal's container // to be created so dimensions are accurate setTimeout(() => { - this._processManager!.createProcess(this._shellLaunchConfig, this._cols, this._rows); + this._processManager!.createProcess(this._shellLaunchConfig, this._cols, this._rows, this._isScreenReaderOptimized()); }, 0); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index 723cbe41cd42f..2f3f36007815b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -100,7 +100,8 @@ export class TerminalProcessManager implements ITerminalProcessManager { public async createProcess( shellLaunchConfig: IShellLaunchConfig, cols: number, - rows: number + rows: number, + isScreenReaderModeEnabled: boolean ): Promise { const forceExtHostProcess = (this._configHelper.config as any).extHostProcess; if (shellLaunchConfig.cwd && typeof shellLaunchConfig.cwd === 'object') { @@ -127,7 +128,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot(); this._process = this._instantiationService.createInstance(TerminalProcessExtHostProxy, this._terminalId, shellLaunchConfig, activeWorkspaceRootUri, cols, rows, this._configHelper); } else { - this._process = await this._launchProcess(shellLaunchConfig, cols, rows); + this._process = await this._launchProcess(shellLaunchConfig, cols, rows, isScreenReaderModeEnabled); } this.processState = ProcessState.LAUNCHING; @@ -161,7 +162,12 @@ export class TerminalProcessManager implements ITerminalProcessManager { }, LAUNCHING_DURATION); } - private async _launchProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): Promise { + private async _launchProcess( + shellLaunchConfig: IShellLaunchConfig, + cols: number, + rows: number, + isScreenReaderModeEnabled: boolean + ): Promise { if (!shellLaunchConfig.executable) { const defaultConfig = await this._terminalInstanceService.getDefaultShellAndArgs(); shellLaunchConfig.executable = defaultConfig.shell; @@ -178,7 +184,7 @@ export class TerminalProcessManager implements ITerminalProcessManager { const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv(); const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); - const useConpty = this._configHelper.config.windowsEnableConpty; + const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled; return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty); } diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index a241d24ace059..7d237e386ed80 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -701,7 +701,7 @@ export interface ITerminalProcessManager extends IDisposable { readonly onProcessExit: Event; dispose(immediate?: boolean): void; - createProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number): Promise; + createProcess(shellLaunchConfig: IShellLaunchConfig, cols: number, rows: number, isScreenReaderModeEnabled: boolean): Promise; write(data: string): void; setDimensions(cols: number, rows: number): void; From 8119b4aee7eba7e4370e2aebd7cd7340881607e8 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 15:42:14 -0700 Subject: [PATCH 313/364] Move the webviewResourceRoot property to be set on each webview instead of as a global property For #72155 This allows us to potentially change the resource root per webview --- .../src/features/preview.ts | 2 +- .../src/features/previewContentProvider.ts | 51 ++++++++++--------- .../src/markdownExtensions.ts | 3 +- .../src/util/resources.ts | 4 +- .../src/singlefolder-tests/webview.test.ts | 2 +- src/vs/vscode.proposed.d.ts | 4 +- .../api/browser/mainThreadCodeInsets.ts | 6 +++ .../api/browser/mainThreadWebview.ts | 6 +++ .../workbench/api/common/extHost.protocol.ts | 3 +- .../workbench/api/common/extHostCodeInsets.ts | 4 ++ src/vs/workbench/api/common/extHostWebview.ts | 4 ++ src/vs/workbench/api/node/extHost.api.impl.ts | 4 -- .../common/remoteExtensionHostClient.ts | 1 - .../electron-browser/extensionHost.ts | 1 - 14 files changed, 57 insertions(+), 38 deletions(-) diff --git a/extensions/markdown-language-features/src/features/preview.ts b/extensions/markdown-language-features/src/features/preview.ts index 0bb67dccd4c5c..5f4a03275ff5e 100644 --- a/extensions/markdown-language-features/src/features/preview.ts +++ b/extensions/markdown-language-features/src/features/preview.ts @@ -412,7 +412,7 @@ export class MarkdownPreview extends Disposable { this.currentVersion = pendingVersion; if (this._resource === resource) { - const content = await this._contentProvider.provideTextDocumentContent(document, this._previewConfigurations, this.line, this.state); + const content = await this._contentProvider.provideTextDocumentContent(document, await this.editor.webview.resourceRoot, this._previewConfigurations, this.line, this.state); // Another call to `doUpdate` may have happened. // Make sure we are still updating for the correct document if (this.currentVersion && this.currentVersion.equals(pendingVersion)) { diff --git a/extensions/markdown-language-features/src/features/previewContentProvider.ts b/extensions/markdown-language-features/src/features/previewContentProvider.ts index 57edf1bd26d10..00bcf723aab36 100644 --- a/extensions/markdown-language-features/src/features/previewContentProvider.ts +++ b/extensions/markdown-language-features/src/features/previewContentProvider.ts @@ -51,6 +51,7 @@ export class MarkdownContentProvider { public async provideTextDocumentContent( markdownDocument: vscode.TextDocument, + webviewResourceRoot: string, previewConfigurations: MarkdownPreviewConfigurationManager, initialLine: number | undefined = undefined, state?: any @@ -65,14 +66,14 @@ export class MarkdownContentProvider { scrollEditorWithPreview: config.scrollEditorWithPreview, doubleClickToSwitchToEditor: config.doubleClickToSwitchToEditor, disableSecurityWarnings: this.cspArbiter.shouldDisableSecurityWarnings(), - webviewResourceRoot: vscode.env.webviewResourceRoot, + webviewResourceRoot: webviewResourceRoot, }; this.logger.log('provideTextDocumentContent', initialData); // Content Security Policy const nonce = new Date().getTime() + '' + new Date().getMilliseconds(); - const csp = this.getCspForResource(sourceUri, nonce); + const csp = this.getCspForResource(webviewResourceRoot, sourceUri, nonce); const body = await this.engine.render(markdownDocument); return ` @@ -84,14 +85,14 @@ export class MarkdownContentProvider { data-settings="${escapeAttribute(JSON.stringify(initialData))}" data-strings="${escapeAttribute(JSON.stringify(previewStrings))}" data-state="${escapeAttribute(JSON.stringify(state || {}))}"> - - ${this.getStyles(sourceUri, nonce, config, state)} - + + ${this.getStyles(webviewResourceRoot, sourceUri, nonce, config, state)} + ${body}
- ${this.getScripts(nonce)} + ${this.getScripts(webviewResourceRoot, nonce)} `; } @@ -109,12 +110,12 @@ export class MarkdownContentProvider { `; } - private extensionResourcePath(mediaFile: string): string { - return toResoruceUri(vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile)))) + private extensionResourcePath(webviewResourceRoot: string, mediaFile: string): string { + return toResoruceUri(webviewResourceRoot, vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile)))) .toString(); } - private fixHref(resource: vscode.Uri, href: string): string { + private fixHref(webviewResourceRoot: string, resource: vscode.Uri, href: string): string { if (!href) { return href; } @@ -125,23 +126,23 @@ export class MarkdownContentProvider { // Assume it must be a local file if (path.isAbsolute(href)) { - return toResoruceUri(vscode.Uri.file(href)).toString(); + return toResoruceUri(webviewResourceRoot, vscode.Uri.file(href)).toString(); } // Use a workspace relative path if there is a workspace const root = vscode.workspace.getWorkspaceFolder(resource); if (root) { - return toResoruceUri(vscode.Uri.file(path.join(root.uri.fsPath, href))).toString(); + return toResoruceUri(webviewResourceRoot, vscode.Uri.file(path.join(root.uri.fsPath, href))).toString(); } // Otherwise look relative to the markdown file - return toResoruceUri(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString(); + return toResoruceUri(webviewResourceRoot, vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString(); } - private computeCustomStyleSheetIncludes(resource: vscode.Uri, config: MarkdownPreviewConfiguration): string { + private computeCustomStyleSheetIncludes(webviewResourceRoot: string, resource: vscode.Uri, config: MarkdownPreviewConfiguration): string { if (Array.isArray(config.styles)) { return config.styles.map(style => { - return ``; + return ``; }).join('\n'); } return ''; @@ -172,37 +173,41 @@ export class MarkdownContentProvider { return ret; } - private getStyles(resource: vscode.Uri, nonce: string, config: MarkdownPreviewConfiguration, state?: any): string { + private getStyles(webviewResourceRoot: string, resource: vscode.Uri, nonce: string, config: MarkdownPreviewConfiguration, state?: any): string { const baseStyles = this.contributionProvider.contributions.previewStyles - .map(resource => ``) + .map(resource => ``) .join('\n'); return `${baseStyles} ${this.getSettingsOverrideStyles(nonce, config)} - ${this.computeCustomStyleSheetIncludes(resource, config)} + ${this.computeCustomStyleSheetIncludes(webviewResourceRoot, resource, config)} ${this.getImageStabilizerStyles(state)}`; } - private getScripts(nonce: string): string { + private getScripts(resourceRoot: string, nonce: string): string { return this.contributionProvider.contributions.previewScripts - .map(resource => ``) + .map(resource => ``) .join('\n'); } - private getCspForResource(resource: vscode.Uri, nonce: string): string { + private getCspForResource( + webviewResourceRoot: string, + resource: vscode.Uri, + nonce: string + ): string { switch (this.cspArbiter.getSecurityLevelForResource(resource)) { case MarkdownPreviewSecurityLevel.AllowInsecureContent: - return ``; + return ``; case MarkdownPreviewSecurityLevel.AllowInsecureLocalContent: - return ``; + return ``; case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent: return ''; case MarkdownPreviewSecurityLevel.Strict: default: - return ``; + return ``; } } } diff --git a/extensions/markdown-language-features/src/markdownExtensions.ts b/extensions/markdown-language-features/src/markdownExtensions.ts index ffbdc3054b847..b03c5df80bd48 100644 --- a/extensions/markdown-language-features/src/markdownExtensions.ts +++ b/extensions/markdown-language-features/src/markdownExtensions.ts @@ -7,10 +7,9 @@ import * as vscode from 'vscode'; import * as path from 'path'; import { Disposable } from './util/dispose'; import * as arrays from './util/arrays'; -import { toResoruceUri } from './util/resources'; const resolveExtensionResource = (extension: vscode.Extension, resourcePath: string): vscode.Uri => { - return toResoruceUri(vscode.Uri.file(path.join(extension.extensionPath, resourcePath))); + return vscode.Uri.file(path.join(extension.extensionPath, resourcePath)); }; const resolveExtensionResources = (extension: vscode.Extension, resourcePaths: unknown): vscode.Uri[] => { diff --git a/extensions/markdown-language-features/src/util/resources.ts b/extensions/markdown-language-features/src/util/resources.ts index f7133f5a0c41d..cb9b8cb56d6c9 100644 --- a/extensions/markdown-language-features/src/util/resources.ts +++ b/extensions/markdown-language-features/src/util/resources.ts @@ -5,9 +5,9 @@ import * as vscode from 'vscode'; -const rootUri = vscode.Uri.parse(vscode.env.webviewResourceRoot); -export function toResoruceUri(uri: vscode.Uri): vscode.Uri { +export function toResoruceUri(webviewResourceRoot: string, uri: vscode.Uri): vscode.Uri { + const rootUri = vscode.Uri.parse(webviewResourceRoot); return rootUri.with({ path: rootUri.path + uri.path, query: uri.query, diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts index 01e8b460efa6a..8ef8cec74d668 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/webview.test.ts @@ -251,7 +251,7 @@ suite('Webview tests', () => { }); `); - const workspaceRootUri = vscode.env.webviewResourceRoot + vscode.Uri.file(vscode.workspace.rootPath!).path; + const workspaceRootUri = webview.webview.resourceRoot + vscode.Uri.file(vscode.workspace.rootPath!).path; { const imagePath = workspaceRootUri.toString() + '/image.png'; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 86d4ae370b651..f1849eb35e9dd 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1461,14 +1461,14 @@ declare module 'vscode' { //#region Webview Resource Roots - export namespace env { + export interface Webview { /** * Root url from which local resources are loaded inside of webviews. * * This is `vscode-resource:` when vscode is run on the desktop. When vscode is run * on the web, this points to a server endpoint. */ - export const webviewResourceRoot: string; + readonly resourceRoot: Thenable; } //#endregion diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index 378fb000ddbdb..e06a5dc3ea99c 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -12,6 +12,7 @@ import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/we import { DisposableStore } from 'vs/base/common/lifecycle'; import { IActiveCodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; // todo@joh move these things back into something like contrib/insets class EditorWebviewZone implements IViewZone { @@ -59,6 +60,7 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { constructor( context: IExtHostContext, + @IEnvironmentService private readonly _environmentService: IEnvironmentService, @ICodeEditorService private readonly _editorService: ICodeEditorService, @IWebviewService private readonly _webviewService: IWebviewService, ) { @@ -144,4 +146,8 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { } return Promise.resolve(false); } + + async $getResourceRoot(_handle: number): Promise { + return this._environmentService.webviewResourceRoot; + } } diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index 83b6403e4f582..5dd98e6e0d65d 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -23,6 +23,7 @@ import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/commo import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { extHostNamedCustomer } from '../common/extHostCustomers'; import { IProductService } from 'vs/platform/product/common/product'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @extHostNamedCustomer(MainContext.MainThreadWebviews) export class MainThreadWebviews extends Disposable implements MainThreadWebviewsShape { @@ -54,6 +55,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews @IOpenerService private readonly _openerService: IOpenerService, @ITelemetryService private readonly _telemetryService: ITelemetryService, @IProductService private readonly _productService: IProductService, + @IEnvironmentService private readonly _environmentService: IEnvironmentService, ) { super(); @@ -139,6 +141,10 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews webview.setOptions(reviveWebviewOptions(options as any /*todo@mat */)); } + async $getResourceRoot(_handle: WebviewPanelHandle): Promise { + return this._environmentService.webviewResourceRoot; + } + public $reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void { const webview = this.getWebview(handle); if (webview.isDisposed()) { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index f40201b71c3e6..2de332144235f 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -59,7 +59,6 @@ export interface IEnvironment { extensionTestsLocationURI?: URI; globalStorageHome: URI; userHome: URI; - webviewResourceRoot: string; } export interface IStaticWorkspaceData { @@ -519,6 +518,7 @@ export interface MainThreadEditorInsetsShape extends IDisposable { $setHtml(handle: number, value: string): void; $setOptions(handle: number, options: modes.IWebviewOptions): void; $postMessage(handle: number, value: any): Promise; + $getResourceRoot(handle: number): Promise; } export interface ExtHostEditorInsetsShape { @@ -543,6 +543,7 @@ export interface MainThreadWebviewsShape extends IDisposable { $setHtml(handle: WebviewPanelHandle, value: string): void; $setOptions(handle: WebviewPanelHandle, options: modes.IWebviewOptions): void; $postMessage(handle: WebviewPanelHandle, value: any): Promise; + $getResourceRoot(handle: WebviewPanelHandle): Promise; $registerSerializer(viewType: string): void; $unregisterSerializer(viewType: string): void; diff --git a/src/vs/workbench/api/common/extHostCodeInsets.ts b/src/vs/workbench/api/common/extHostCodeInsets.ts index 5a6773d443893..5b40af3d04d9a 100644 --- a/src/vs/workbench/api/common/extHostCodeInsets.ts +++ b/src/vs/workbench/api/common/extHostCodeInsets.ts @@ -61,6 +61,10 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape { private _html: string = ''; private _options: vscode.WebviewOptions; + get resourceRoot(): Promise { + return that._proxy.$getResourceRoot(handle); + } + set options(value: vscode.WebviewOptions) { this._options = value; that._proxy.$setOptions(handle, value); diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index b6ad9c09ee26a..98d6631c2a012 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -39,6 +39,10 @@ export class ExtHostWebview implements vscode.Webview { this._onMessageEmitter.dispose(); } + public get resourceRoot(): Promise { + return this._proxy.$getResourceRoot(this._handle); + } + public get html(): string { this.assertNotDisposed(); return this._html; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 9cff724bc75f9..0548192c90340 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -262,10 +262,6 @@ export function createApiFactory( openExternal(uri: URI) { return extHostWindow.openUri(uri, { allowTunneling: !!initData.remote.isRemote }); }, - get webviewResourceRoot() { - checkProposedApiEnabled(extension); - return initData.environment.webviewResourceRoot; - }, get remoteName() { if (!initData.remote.authority) { return undefined; diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index 5ab1b30e06c75..f43a59b96634b 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -190,7 +190,6 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: remoteExtensionHostData.globalStorageHome, userHome: remoteExtensionHostData.userHome, - webviewResourceRoot: this._environmentService.webviewResourceRoot, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : { configuration: workspace.configuration, diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts index 860845137fca0..3d324296b0186 100644 --- a/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/extensionHost.ts @@ -400,7 +400,6 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter { extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: URI.file(this._environmentService.globalStorageHome), userHome: URI.file(this._environmentService.userHome), - webviewResourceRoot: this._environmentService.webviewResourceRoot, }, workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : { configuration: withNullAsUndefined(workspace.configuration), From e32e2a90c5ae5d914d161b7d66cd818a656223b7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 16:27:17 -0700 Subject: [PATCH 314/364] Make RelativeWorkspacePathResolver a static class --- .../src/utils/pluginPathsProvider.ts | 3 +-- .../src/utils/relativePathResolver.ts | 2 +- .../typescript-language-features/src/utils/versionProvider.ts | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts b/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts index 547660f064928..de6d03cd980c6 100644 --- a/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts +++ b/extensions/typescript-language-features/src/utils/pluginPathsProvider.ts @@ -9,7 +9,6 @@ import { RelativeWorkspacePathResolver } from './relativePathResolver'; export class TypeScriptPluginPathsProvider { - public readonly relativePathResolver: RelativeWorkspacePathResolver = new RelativeWorkspacePathResolver(); public constructor( private configuration: TypeScriptServiceConfiguration @@ -32,7 +31,7 @@ export class TypeScriptPluginPathsProvider { return [pluginPath]; } - const workspacePath = this.relativePathResolver.asAbsoluteWorkspacePath(pluginPath); + const workspacePath = RelativeWorkspacePathResolver.asAbsoluteWorkspacePath(pluginPath); if (workspacePath !== undefined) { return [workspacePath]; } diff --git a/extensions/typescript-language-features/src/utils/relativePathResolver.ts b/extensions/typescript-language-features/src/utils/relativePathResolver.ts index 85b72a55d6b5c..64dff66fb53dc 100644 --- a/extensions/typescript-language-features/src/utils/relativePathResolver.ts +++ b/extensions/typescript-language-features/src/utils/relativePathResolver.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; export class RelativeWorkspacePathResolver { - public asAbsoluteWorkspacePath(relativePath: string): string | undefined { + public static asAbsoluteWorkspacePath(relativePath: string): string | undefined { for (const root of vscode.workspace.workspaceFolders || []) { const rootPrefixes = [`./${root.name}/`, `${root.name}/`, `.\\${root.name}\\`, `${root.name}\\`]; for (const rootPrefix of rootPrefixes) { diff --git a/extensions/typescript-language-features/src/utils/versionProvider.ts b/extensions/typescript-language-features/src/utils/versionProvider.ts index 901446130bd9c..8e9e9a2a8c6f4 100644 --- a/extensions/typescript-language-features/src/utils/versionProvider.ts +++ b/extensions/typescript-language-features/src/utils/versionProvider.ts @@ -88,7 +88,6 @@ export class TypeScriptVersion { } export class TypeScriptVersionProvider { - private readonly relativePathResolver: RelativeWorkspacePathResolver = new RelativeWorkspacePathResolver(); public constructor( private configuration: TypeScriptServiceConfiguration @@ -179,7 +178,7 @@ export class TypeScriptVersionProvider { return [new TypeScriptVersion(tsdkPathSetting)]; } - const workspacePath = this.relativePathResolver.asAbsoluteWorkspacePath(tsdkPathSetting); + const workspacePath = RelativeWorkspacePathResolver.asAbsoluteWorkspacePath(tsdkPathSetting); if (workspacePath !== undefined) { return [new TypeScriptVersion(workspacePath, tsdkPathSetting)]; } From 14bc8002eb6e8c438cabeccfdd8bd0f7f69d45fb Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 16:28:15 -0700 Subject: [PATCH 315/364] Use openExternal --- .../typescript-language-features/src/utils/versionPicker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/utils/versionPicker.ts b/extensions/typescript-language-features/src/utils/versionPicker.ts index afbda6ef206da..d1827002ee3c0 100644 --- a/extensions/typescript-language-features/src/utils/versionPicker.ts +++ b/extensions/typescript-language-features/src/utils/versionPicker.ts @@ -113,7 +113,7 @@ export class TypeScriptVersionPicker { return { oldVersion: previousVersion, newVersion: shippedVersion }; case MessageAction.learnMore: - vscode.commands.executeCommand('vscode.open', vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); + vscode.env.openExternal(vscode.Uri.parse('https://go.microsoft.com/fwlink/?linkid=839919')); return { oldVersion: this.currentVersion }; default: From 8c8f79dcefde77a5df7a09c22fd85d9309706ab1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 16:35:15 -0700 Subject: [PATCH 316/364] Auto restart when changing typescript.experimental.useSeparateSyntaxServer --- .../typescript-language-features/package.nls.json | 2 +- .../src/tsServer/spawner.ts | 13 ++++++------- .../src/utils/configuration.ts | 9 ++++++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index 569685dec0dc0..10fdddec38297 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -49,7 +49,7 @@ "typescript.problemMatchers.tsc.label": "TypeScript problems", "typescript.problemMatchers.tscWatch.label": "TypeScript problems (watch mode)", "configuration.suggest.paths": "Enable/disable suggestions for paths in import statements and require calls.", - "configuration.experimental.useSeparateSyntaxServer": "Enable/disable spawning a separate TypeScript server that can more quickly respond to syntax related operations, such as calculating folding or computing document symbols. Note that you must restart the TypeScript server after changing this setting. Requires using TypeScript 3.4.0 or newer in the workspace.", + "configuration.experimental.useSeparateSyntaxServer": "Enable/disable spawning a separate TypeScript server that can more quickly respond to syntax related operations, such as calculating folding or computing document symbols. Requires using TypeScript 3.4.0 or newer in the workspace.", "typescript.locale": "Sets the locale used to report JavaScript and TypeScript errors. Requires using TypeScript 2.6.0 or newer in the workspace. Default of `null` uses VS Code's locale.", "javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable `experimentalDecorators` for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.", "configuration.suggest.autoImports": "Enable/disable auto import suggestions. Requires using TypeScript 2.6.1 or newer in the workspace.", diff --git a/extensions/typescript-language-features/src/tsServer/spawner.ts b/extensions/typescript-language-features/src/tsServer/spawner.ts index a7be07a0806bb..599abe32ca1c5 100644 --- a/extensions/typescript-language-features/src/tsServer/spawner.ts +++ b/extensions/typescript-language-features/src/tsServer/spawner.ts @@ -37,7 +37,7 @@ export class TypeScriptServerSpawner { configuration: TypeScriptServiceConfiguration, pluginManager: PluginManager ): ITypeScriptServer { - if (this.shouldUseSeparateSyntaxServer(version)) { + if (this.shouldUseSeparateSyntaxServer(version, configuration)) { const syntaxServer = this.spawnTsServer('syntax', version, configuration, pluginManager); const semanticServer = this.spawnTsServer('semantic', version, configuration, pluginManager); return new SyntaxRoutingTsServer(syntaxServer, semanticServer); @@ -46,12 +46,11 @@ export class TypeScriptServerSpawner { return this.spawnTsServer('main', version, configuration, pluginManager); } - private shouldUseSeparateSyntaxServer(version: TypeScriptVersion): boolean { - if (!version.apiVersion || version.apiVersion.lt(API.v340)) { - return false; - } - return vscode.workspace.getConfiguration('typescript') - .get('experimental.useSeparateSyntaxServer', false); + private shouldUseSeparateSyntaxServer( + version: TypeScriptVersion, + configuration: TypeScriptServiceConfiguration, + ): boolean { + return configuration.useSeparateSyntaxServer && !!version.apiVersion && version.apiVersion.gte(API.v340); } private spawnTsServer( diff --git a/extensions/typescript-language-features/src/utils/configuration.ts b/extensions/typescript-language-features/src/utils/configuration.ts index 3babc53c91b13..976192822560c 100644 --- a/extensions/typescript-language-features/src/utils/configuration.ts +++ b/extensions/typescript-language-features/src/utils/configuration.ts @@ -54,6 +54,7 @@ export class TypeScriptServiceConfiguration { public readonly checkJs: boolean; public readonly experimentalDecorators: boolean; public readonly disableAutomaticTypeAcquisition: boolean; + public readonly useSeparateSyntaxServer: boolean; public static loadFromWorkspace(): TypeScriptServiceConfiguration { return new TypeScriptServiceConfiguration(); @@ -71,6 +72,7 @@ export class TypeScriptServiceConfiguration { this.checkJs = TypeScriptServiceConfiguration.readCheckJs(configuration); this.experimentalDecorators = TypeScriptServiceConfiguration.readExperimentalDecorators(configuration); this.disableAutomaticTypeAcquisition = TypeScriptServiceConfiguration.readDisableAutomaticTypeAcquisition(configuration); + this.useSeparateSyntaxServer = TypeScriptServiceConfiguration.readUseSeparateSyntaxServer(configuration); } public isEqualTo(other: TypeScriptServiceConfiguration): boolean { @@ -82,7 +84,8 @@ export class TypeScriptServiceConfiguration { && this.checkJs === other.checkJs && this.experimentalDecorators === other.experimentalDecorators && this.disableAutomaticTypeAcquisition === other.disableAutomaticTypeAcquisition - && arrays.equals(this.tsServerPluginPaths, other.tsServerPluginPaths); + && arrays.equals(this.tsServerPluginPaths, other.tsServerPluginPaths) + && this.useSeparateSyntaxServer === other.useSeparateSyntaxServer; } private static fixPathPrefixes(inspectValue: string): string { @@ -139,4 +142,8 @@ export class TypeScriptServiceConfiguration { private static extractLocale(configuration: vscode.WorkspaceConfiguration): string | null { return configuration.get('typescript.locale', null); } + + private static readUseSeparateSyntaxServer(configuration: vscode.WorkspaceConfiguration): boolean { + return configuration.get('typescript.experimental.useSeparateSyntaxServer', false); + } } From a77402669cb9d5192974e7cc2da828c52e39fba2 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 17:22:03 -0700 Subject: [PATCH 317/364] Fix regular expression for rewriting iframe webview html replacing quotes --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 98cfb4c089138..1b6c671a68e8b 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -172,7 +172,7 @@ export class IFrameWebview extends Disposable implements Webview { } private preprocessHtml(value: string): string { - return value.replace(/(?:["'])vscode-resource:([^\s'"]+)(?:["'])/gi, '/vscode-resource$1'); + return value.replace(/(?<=["'])vscode-resource:([^\s'"]+)(?=["'])/gi, '/vscode-resource$1'); } public update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean) { From 4a69a7106505b04a82f2be18b89a128198cca651 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 24 Jun 2019 18:47:12 -0700 Subject: [PATCH 318/364] Telemetry Command (#76029) * Added telemetry command * Initial Build support * Added build logic for telemetry * Linux Builds * Windows builds sort of work * Remove arm telemetry extraction * Remove alpine telemetry extraction * Remove accidental s * More try catch --- .../darwin/product-build-darwin.yml | 15 ++++++++ .../linux/product-build-linux.yml | 15 ++++++++ .../win32/product-build-win32.yml | 17 +++++++++ build/gulpfile.vscode.js | 4 ++- resources/completions/zsh/_code | 1 + src/vs/code/node/cli.ts | 3 +- src/vs/code/node/cliProcessMain.ts | 3 ++ .../environment/common/environment.ts | 1 + src/vs/platform/environment/node/argv.ts | 36 ++++++++++++++++++- 9 files changed, 92 insertions(+), 3 deletions(-) diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index b465ef9a09543..0b9a362c07587 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -59,6 +59,21 @@ steps: node build/lib/builtInExtensions.js displayName: Install distro dependencies and extensions +- script: | + set -e + cd .. + git clone https://github.com/microsoft/vscode-telemetry-extractor.git + cd vscode-telemetry-extractor + npm install + ./node_modules/typescript/bin/tsc + npm run setup-extension-repos + node ./out/cli-extract.js --sourceDir ../s --excludedDirPattern extensions --outputDir . --applyEndpoints --includeIsMeasurement --patchWebsiteEvents + node ./out/cli-extract-extensions.js --sourceDir ./src/telemetry-sources/ --outputDir . --applyEndpoints --includeIsMeasurement + mv declarations-resolved.json ../s/src/telemetry-core.json + mv declarations-extensions-resolved.json ../s/src/telemetry-extensions.json + echo 'Moved Files' + displayName: Extract Telemetry + - script: | set -e VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index fa26c26dd1c63..210798a47761c 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -60,6 +60,21 @@ steps: node build/lib/builtInExtensions.js displayName: Install distro dependencies and extensions +- script: | + set -e + cd .. + git clone https://github.com/microsoft/vscode-telemetry-extractor.git + cd vscode-telemetry-extractor + npm install + ./node_modules/typescript/bin/tsc + npm run setup-extension-repos + node ./out/cli-extract.js --sourceDir ../s --excludedDirPattern extensions --outputDir . --applyEndpoints --includeIsMeasurement --patchWebsiteEvents + node ./out/cli-extract-extensions.js --sourceDir ./src/telemetry-sources/ --outputDir . --applyEndpoints --includeIsMeasurement + mv declarations-resolved.json ../s/src/telemetry-core.json + mv declarations-extensions-resolved.json ../s/src/telemetry-extensions.json + echo 'Moved Files' + displayName: Extract Telemetry + - script: | set -e VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 3fe19e4b847b0..31ff866b76ac4 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -65,6 +65,23 @@ steps: exec { node build/lib/builtInExtensions.js } displayName: Install distro dependencies and extensions +- powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + cd .. + git clone https://github.com/microsoft/vscode-telemetry-extractor.git + cd vscode-telemetry-extractor + npm install + npm install -g typescript + tsc + npm run setup-extension-repos + node ./out/cli-extract.js --sourceDir ../s --excludedDirPattern extensions --outputDir . --applyEndpoints --includeIsMeasurement --patchWebsiteEvents + node ./out/cli-extract-extensions.js --sourceDir ./src/telemetry-sources/ --outputDir . --applyEndpoints --includeIsMeasurement + mv declarations-resolved.json ../s/src/telemetry-core.json + mv declarations-extensions-resolved.json ../s/src/telemetry-extensions.json + echo 'Moved Files' + displayName: Extract Telemetry + - powershell: | . build/azure-pipelines/win32/exec.ps1 $ErrorActionPreference = "Stop" diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 9c32df0bf81e1..4fc0a7ff41469 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -62,6 +62,8 @@ const vscodeResources = [ 'out-build/bootstrap-amd.js', 'out-build/bootstrap-window.js', 'out-build/paths.js', + 'out-build/telemetry-core.json', + 'out-build/telemetry-extensions.json', 'out-build/vs/**/*.{svg,png,cur,html}', '!out-build/vs/code/browser/**/*.html', 'out-build/vs/base/common/performance.js', @@ -327,7 +329,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op .pipe(createAsar(path.join(process.cwd(), 'node_modules'), ['**/*.node', '**/vscode-ripgrep/bin/*', '**/node-pty/build/Release/*'], 'app/node_modules.asar')); let all = es.merge( - packageJsonStream, + packageJsonStream, productJsonStream, license, api, diff --git a/resources/completions/zsh/_code b/resources/completions/zsh/_code index 8c4415ac59f0d..054ab351e9169 100644 --- a/resources/completions/zsh/_code +++ b/resources/completions/zsh/_code @@ -14,6 +14,7 @@ arguments=( '--user-data-dir[specify the directory that user data is kept in]:directory:_directories' '(- *)'{-v,--version}'[print version]' '(- *)'{-h,--help}'[print usage]' + '(- *)'{--telemetry}'[Shows all telemetry events which VS code collects.]' '--extensions-dir[set the root path for extensions]:root path:_directories' '--list-extensions[list the installed extensions]' '--show-versions[show versions of installed extensions, when using --list-extension]' diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 45f4ff7d6706a..978ecdd42b861 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -25,7 +25,8 @@ function shouldSpawnCliProcess(argv: ParsedArgs): boolean { || !!argv['list-extensions'] || !!argv['install-extension'] || !!argv['uninstall-extension'] - || !!argv['locate-extension']; + || !!argv['locate-extension'] + || !!argv['telemetry']; } interface IMainCli { diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index dafebd1c91f64..5caccaf03b9d2 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -41,6 +41,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { Schemas } from 'vs/base/common/network'; import { SpdLogService } from 'vs/platform/log/node/spdlogService'; +import { buildTelemetryMessage } from 'vs/platform/environment/node/argv'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -94,6 +95,8 @@ export class Main { const arg = argv['locate-extension']; const ids: string[] = typeof arg === 'string' ? [arg] : arg; await this.locateExtension(ids); + } else if (argv['telemetry']) { + console.log(buildTelemetryMessage(this.environmentService.appRoot, this.environmentService.extensionsPath)); } } diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 443e430fcd0e9..dc75380ba1868 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -13,6 +13,7 @@ export interface ParsedArgs { _urls?: string[]; help?: boolean; version?: boolean; + telemetry?: boolean; status?: boolean; wait?: boolean; waitMarkerFilePath?: string; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index b53a29f370aac..a8715ddccae98 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -8,7 +8,8 @@ import * as os from 'os'; import { localize } from 'vs/nls'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { join } from 'vs/base/common/path'; -import { writeFileSync } from 'vs/base/node/pfs'; +import { statSync, readFileSync } from 'fs'; +import { writeFileSync, readdirSync } from 'vs/base/node/pfs'; /** * This code is also used by standalone cli's. Avoid adding any other dependencies. @@ -41,6 +42,7 @@ export const options: Option[] = [ { id: 'user-data-dir', type: 'string', cat: 'o', args: 'dir', description: localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.") }, { id: 'version', type: 'boolean', cat: 'o', alias: 'v', description: localize('version', "Print version.") }, { id: 'help', type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") }, + { id: 'telemetry', type: 'boolean', cat: 'o', description: localize('telemetry', "Shows all telemetry events which VS code collects.") }, { id: 'folder-uri', type: 'string', cat: 'o', args: 'uri', description: localize('folderUri', "Opens a window with given folder uri(s)") }, { id: 'file-uri', type: 'string', cat: 'o', args: 'uri', description: localize('fileUri', "Opens a window with given file uri(s)") }, @@ -217,6 +219,38 @@ export function buildVersionMessage(version: string | undefined, commit: string return `${version || localize('unknownVersion', "Unknown version")}\n${commit || localize('unknownCommit', "Unknown commit")}\n${process.arch}`; } +export function buildTelemetryMessage(appRoot: string, extensionsPath: string): string { + try { + // Gets all the directories inside the extension directory + const dirs = readdirSync(extensionsPath).filter(files => statSync(join(extensionsPath, files)).isDirectory()); + const telemetryJsonFolders: string[] = []; + dirs.forEach((dir) => { + const files = readdirSync(join(extensionsPath, dir)).filter(file => file === 'telemetry.json'); + // We know it contains a telemetry.json file so we add it to the list of folders which have one + if (files.length === 1) { + telemetryJsonFolders.push(dir); + } + }); + const mergedTelemetry = Object.create(null); + // Simple function to merge the telemetry into one json object + const mergeTelemetry = (contents: string, dirName: string) => { + const telemetryData = JSON.parse(contents); + mergedTelemetry[dirName] = telemetryData; + }; + telemetryJsonFolders.forEach((folder) => { + const contents = readFileSync(join(extensionsPath, folder, 'telemetry.json')).toString(); + mergeTelemetry(contents, folder); + }); + let contents = readFileSync(join(appRoot, 'out/', 'telemetry-core.json')).toString(); + mergeTelemetry(contents, 'vscode-core'); + contents = readFileSync(join(appRoot, 'out/', 'telemetry-extensions.json')).toString(); + mergeTelemetry(contents, 'vscode-extensions'); + return JSON.stringify(mergedTelemetry, null, 4); + } catch (err) { + return 'Unable to read VS Code telemetry events!'; + } +} + /** * Converts an argument into an array * @param arg a argument value. Can be undefined, an entry or an array From 9690e3b17e060b356a6c871234c29f82f69f7b73 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 17:56:40 -0700 Subject: [PATCH 319/364] Use full resource uri for transforming webview resources This ensures we still work even if there is no base uri set --- product.json | 9 ++++++++- .../workbench/contrib/webview/browser/webviewElement.ts | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/product.json b/product.json index 4103352af85f3..8037965bff05f 100644 --- a/product.json +++ b/product.json @@ -22,5 +22,12 @@ "urlProtocol": "code-oss", "extensionAllowedProposedApi": [ "ms-vscode.references-view" - ] + ], + "extensionsGallery": { + "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery", + "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index", + "itemUrl": "https://marketplace.visualstudio.com/items", + "controlUrl": "https://az764295.vo.msecnd.net/extensions/marketplace.json", + "recommendationsUrl": "https://az764295.vo.msecnd.net/extensions/workspaceRecommendations.json.gz" + } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 1b6c671a68e8b..f64f439ece05d 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -40,8 +40,8 @@ export class IFrameWebview extends Disposable implements Webview { private _options: WebviewOptions, contentOptions: WebviewContentOptions, @IThemeService themeService: IThemeService, - @IEnvironmentService environmentService: IEnvironmentService, @ITunnelService tunnelService: ITunnelService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, @IFileService private readonly fileService: IFileService, @IConfigurationService private readonly _configurationService: IConfigurationService, ) { @@ -172,7 +172,7 @@ export class IFrameWebview extends Disposable implements Webview { } private preprocessHtml(value: string): string { - return value.replace(/(?<=["'])vscode-resource:([^\s'"]+)(?=["'])/gi, '/vscode-resource$1'); + return value.replace(/(?<=["'])vscode-resource:([^\s'"]+)(?=["'])/gi, `${this.environmentService.webviewEndpoint}/vscode-resource$1`); } public update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean) { From c281e61ad17bf7be379d835371a746b540c718af Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 19:51:02 -0700 Subject: [PATCH 320/364] Use outerHtml to make sure we write `` element from extensions too --- src/vs/workbench/contrib/webview/browser/pre/main.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index c30f0c79592bf..c4f638e1ce296 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -370,8 +370,7 @@ newFrame.contentWindow.addEventListener('DOMContentLoaded', e => { if (FAKE_LOAD) { newFrame.contentDocument.open(); - newFrame.contentDocument.write(''); - newFrame.contentDocument.write(newDocument.documentElement.innerHTML); + newFrame.contentDocument.write('\n' + newDocument.documentElement.outerHTML); newFrame.contentDocument.close(); hookupOnLoadHandlers(newFrame); } @@ -496,4 +495,4 @@ } else { window.createWebviewManager = createWebviewManager; } -}()); \ No newline at end of file +}()); From 7a6ed6d5c94551dfa3bd22cc3837a6fbe90eccfe Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 19:51:26 -0700 Subject: [PATCH 321/364] Use a regexp that works across browsers --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index f64f439ece05d..1d82afae00611 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -172,7 +172,8 @@ export class IFrameWebview extends Disposable implements Webview { } private preprocessHtml(value: string): string { - return value.replace(/(?<=["'])vscode-resource:([^\s'"]+)(?=["'])/gi, `${this.environmentService.webviewEndpoint}/vscode-resource$1`); + return value.replace(/(["'])vscode-resource:([^\s'"]+?)(["'])/gi, (_, startQuote, path, endQuote) => + `${startQuote}${this.environmentService.webviewEndpoint}/vscode-resource${path}${endQuote}`); } public update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean) { From b78d8d5056331efaee1e2790fa1041550cb8934d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 24 Jun 2019 19:51:51 -0700 Subject: [PATCH 322/364] Implement reload on iframe based webview Elements --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 1d82afae00611..247c1366e728e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -246,8 +246,9 @@ export class IFrameWebview extends Disposable implements Webview { } reload(): void { - throw new Error('Method not implemented.'); + this.doUpdateContent(); } + selectAll(): void { throw new Error('Method not implemented.'); } From c673aa0cdc211510b6d88b783971b20c4745b054 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 06:43:05 +0200 Subject: [PATCH 323/364] fix various nls issues --- .../codeEditor/browser/inspectKeybindings.ts | 4 ++-- .../preferences/browser/keyboardLayoutPicker.ts | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts b/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts index ec27d6a2e2282..381de357c7e69 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/inspectKeybindings.ts @@ -37,7 +37,7 @@ registerEditorAction(InspectKeyMap); class InspectKeyMapJSON extends Action { public static readonly ID = 'workbench.action.inspectKeyMappingsJSON'; - public static readonly LABEL = nls.localize('workbench.action.inspectKeyMapJSON', "Developer: Inspect Key Mappings (JSON)"); + public static readonly LABEL = nls.localize('workbench.action.inspectKeyMapJSON', "Inspect Key Mappings (JSON)"); constructor( id: string, @@ -54,4 +54,4 @@ class InspectKeyMapJSON extends Action { } const registry = Registry.as(ActionExtensions.WorkbenchActions); -registry.registerWorkbenchAction(new SyncActionDescriptor(InspectKeyMapJSON, InspectKeyMapJSON.ID, InspectKeyMapJSON.LABEL), 'Developer: Inspect Key Mappings (JSON)'); +registry.registerWorkbenchAction(new SyncActionDescriptor(InspectKeyMapJSON, InspectKeyMapJSON.ID, InspectKeyMapJSON.LABEL), 'Developer: Inspect Key Mappings (JSON)', nls.localize('developer', "Developer")); diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 043e3dd6e2a48..1c35cfab123b6 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -37,12 +37,11 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor let layoutInfo = parseKeyboardLayoutDescription(layout); this.pickerElement.value = this.statusbarService.addEntry( { - text: `Layout: ${layoutInfo.label}`, - // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), + text: nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label), command: KEYBOARD_LAYOUT_OPEN_PICKER }, 'status.workbench.keyboardLayout', - nls.localize('status.workbench.keyboardLayout', "Current keyboard layout"), + nls.localize('status.workbench.keyboardLayout', "Current Keyboard Layout"), StatusbarAlignment.RIGHT ); } @@ -53,18 +52,17 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor if (this.pickerElement.value) { this.pickerElement.value.update({ - text: `Layout: ${layoutInfo.label}`, + text: nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label), command: KEYBOARD_LAYOUT_OPEN_PICKER }); } else { this.pickerElement.value = this.statusbarService.addEntry( { - text: `Layout: ${layoutInfo}`, - // tooltip: nls.localize('keyboard.layout.tooltip', "If you are not using a Screen Reader, please change the setting `editor.accessibilitySupport` to \"off\"."), + text: nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label), command: KEYBOARD_LAYOUT_OPEN_PICKER }, 'status.workbench.keyboardLayout', - nls.localize('status.workbench.keyboardLayout', "Current keyboard layout"), + nls.localize('status.workbench.keyboardLayout', "Current Keyboard Layout"), StatusbarAlignment.RIGHT ); } @@ -81,7 +79,7 @@ interface LayoutQuickPickItem extends IQuickPickItem { export class KeyboardLayoutPickerAction extends Action { static readonly ID = KEYBOARD_LAYOUT_OPEN_PICKER; - static readonly LABEL = nls.localize('keyboard.chooseLayout', "Change keyboard layout"); + static readonly LABEL = nls.localize('keyboard.chooseLayout', "Change Keyboard Layout"); private static DEFAULT_CONTENT: string = [ `// ${nls.localize('displayLanguage', 'Defines the keyboard layout used in VS Code in the browser environment.')}`, @@ -180,4 +178,4 @@ export class KeyboardLayoutPickerAction extends Action { } const registry = Registry.as(ActionExtensions.WorkbenchActions); -registry.registerWorkbenchAction(new SyncActionDescriptor(KeyboardLayoutPickerAction, KeyboardLayoutPickerAction.ID, KeyboardLayoutPickerAction.LABEL, {}), 'Change Language Mode'); +registry.registerWorkbenchAction(new SyncActionDescriptor(KeyboardLayoutPickerAction, KeyboardLayoutPickerAction.ID, KeyboardLayoutPickerAction.LABEL, {}), 'Preferences: Change Keyboard Layout', nls.localize('preferences', "Preferences")); From cd206b1f4962f2bd421ecbe87c5a98f630a28860 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 06:46:04 +0200 Subject: [PATCH 324/364] :lipstick: --- .../contrib/preferences/browser/keyboardLayoutPicker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts index 1c35cfab123b6..35a40b06fea10 100644 --- a/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts +++ b/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.ts @@ -41,7 +41,7 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor command: KEYBOARD_LAYOUT_OPEN_PICKER }, 'status.workbench.keyboardLayout', - nls.localize('status.workbench.keyboardLayout', "Current Keyboard Layout"), + nls.localize('status.workbench.keyboardLayout', "Keyboard Layout"), StatusbarAlignment.RIGHT ); } @@ -62,7 +62,7 @@ export class KeyboardLayoutPickerContribution extends Disposable implements IWor command: KEYBOARD_LAYOUT_OPEN_PICKER }, 'status.workbench.keyboardLayout', - nls.localize('status.workbench.keyboardLayout', "Current Keyboard Layout"), + nls.localize('status.workbench.keyboardLayout', "Keyboard Layout"), StatusbarAlignment.RIGHT ); } From 8ad4bab72127a98c217f84351bac1a43f17a8ed0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 08:20:10 +0200 Subject: [PATCH 325/364] add debug output (#76024) --- build/azure-pipelines/common/symbols.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/azure-pipelines/common/symbols.ts b/build/azure-pipelines/common/symbols.ts index a42342ce7f74d..e719e79842e4a 100644 --- a/build/azure-pipelines/common/symbols.ts +++ b/build/azure-pipelines/common/symbols.ts @@ -146,6 +146,10 @@ async function ensureVersionAndSymbols(options: IOptions) { // Check version does not exist console.log(`HockeyApp: checking for existing version ${options.versions.code} (${options.platform})`); const versions = await getVersions({ accessToken: options.access.hockeyAppToken, appId: options.access.hockeyAppId }); + if (!Array.isArray(versions.app_versions)) { + throw new Error(`Unexpected response: ${JSON.stringify(versions)}`); + } + if (versions.app_versions.some(v => v.version === options.versions.code)) { console.log(`HockeyApp: Returning without uploading symbols because version ${options.versions.code} (${options.platform}) was already found`); return; @@ -211,7 +215,7 @@ if (repository && codeVersion && electronVersion && (product.quality === 'stable }).then(() => { console.log('HockeyApp: done'); }).catch(error => { - console.error(`HockeyApp: error (${error})`); + console.error(`HockeyApp: error ${error} (AppID: ${hockeyAppId})`); }); } else { console.log(`HockeyApp: skipping due to unexpected context (repository: ${repository}, codeVersion: ${codeVersion}, electronVersion: ${electronVersion}, quality: ${product.quality})`); From 33eae179e458f2334636e0f90f35f625f34c663b Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 25 Jun 2019 09:36:57 +0200 Subject: [PATCH 326/364] Fix tasks platform for quoting Fixes #75774 --- .../workbench/contrib/tasks/browser/terminalTaskSystem.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts index 4b33e41969b8e..b9739fc680915 100644 --- a/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts +++ b/src/vs/workbench/contrib/tasks/browser/terminalTaskSystem.ts @@ -145,9 +145,9 @@ export class TerminalTaskSystem implements ITaskSystem { }; private static osShellQuotes: IStringDictionary = { - 'linux': TerminalTaskSystem.shellQuotes['bash'], - 'darwin': TerminalTaskSystem.shellQuotes['bash'], - 'win32': TerminalTaskSystem.shellQuotes['powershell'] + 'Linux': TerminalTaskSystem.shellQuotes['bash'], + 'Mac': TerminalTaskSystem.shellQuotes['bash'], + 'Windows': TerminalTaskSystem.shellQuotes['powershell'] }; private activeTasks: IStringDictionary; @@ -1123,7 +1123,7 @@ export class TerminalTaskSystem implements ITaskSystem { if (shellOptions && shellOptions.quoting) { return shellOptions.quoting; } - return TerminalTaskSystem.shellQuotes[shellBasename] || TerminalTaskSystem.osShellQuotes[platform]; + return TerminalTaskSystem.shellQuotes[shellBasename] || TerminalTaskSystem.osShellQuotes[Platform.PlatformToString(platform)]; } private collectTaskVariables(variables: Set, task: CustomTask | ContributedTask): void { From 97108901287435324a993d6da4be38f7f982a935 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 09:45:56 +0200 Subject: [PATCH 327/364] fix hockeyapp symbols and report errors (fix #76024) --- build/azure-pipelines/common/symbols.ts | 6 ++++++ build/azure-pipelines/win32/product-build-win32.yml | 1 + 2 files changed, 7 insertions(+) diff --git a/build/azure-pipelines/common/symbols.ts b/build/azure-pipelines/common/symbols.ts index e719e79842e4a..153be4f25b1c2 100644 --- a/build/azure-pipelines/common/symbols.ts +++ b/build/azure-pipelines/common/symbols.ts @@ -188,6 +188,10 @@ const hockeyAppToken = process.argv[3]; const is64 = process.argv[4] === 'x64'; const hockeyAppId = process.argv[5]; +if (process.argv.length !== 6) { + throw new Error(`HockeyApp: Unexpected number of arguments. Got ${process.argv}`); +} + let platform: Platform; if (process.platform === 'darwin') { platform = Platform.MAC_OS; @@ -216,6 +220,8 @@ if (repository && codeVersion && electronVersion && (product.quality === 'stable console.log('HockeyApp: done'); }).catch(error => { console.error(`HockeyApp: error ${error} (AppID: ${hockeyAppId})`); + + return process.exit(1); }); } else { console.log(`HockeyApp: skipping due to unexpected context (repository: ${repository}, codeVersion: ${codeVersion}, electronVersion: ${electronVersion}, quality: ${product.quality})`); diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 31ff866b76ac4..6efaa050dcc71 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -185,6 +185,7 @@ steps: $env:AZURE_STORAGE_ACCESS_KEY_2 = "$(vscode-storage-key)" $env:AZURE_DOCUMENTDB_MASTERKEY = "$(builds-docdb-key-readwrite)" $env:VSCODE_HOCKEYAPP_TOKEN = "$(vscode-hockeyapp-token)" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" .\build\azure-pipelines\win32\publish.ps1 displayName: Publish From 57b7f06fac63e3f87c85bed74879ed21bfabcf0d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 25 Jun 2019 09:46:32 +0200 Subject: [PATCH 328/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7c10b4b0a7e7..f8690b7cfbc5a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "f22db93b3c64b0787d98aef556519af82c64860b", + "distro": "49ce758993a685b0f621eb6cd9353908ea4eeda4", "author": { "name": "Microsoft Corporation" }, From c7b6044d0f09f1f563ec2a7b86e494b3d55937c9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 25 Jun 2019 11:40:46 +0200 Subject: [PATCH 329/364] fix bad watch --- extensions/git/src/repository.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 6018648f468dc..bec7ce5ead730 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -488,7 +488,10 @@ class DotGitWatcher implements IFileWatcher { private transientDisposables: IDisposable[] = []; private disposables: IDisposable[] = []; - constructor(private repository: Repository) { + constructor( + private repository: Repository, + private outputChannel: OutputChannel + ) { const rootWatcher = watch(repository.dotGit); this.disposables.push(rootWatcher); @@ -511,9 +514,15 @@ class DotGitWatcher implements IFileWatcher { const { name, remote } = this.repository.HEAD.upstream; const upstreamPath = path.join(this.repository.dotGit, 'refs', 'remotes', remote, name); - const upstreamWatcher = watch(upstreamPath); - this.transientDisposables.push(upstreamWatcher); - upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables); + try { + const upstreamWatcher = watch(upstreamPath); + this.transientDisposables.push(upstreamWatcher); + upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables); + } catch (err) { + if (env.logLevel <= LogLevel.Info) { + this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}'. Ref is most likely packed.`); + } + } } dispose() { @@ -642,7 +651,7 @@ export class Repository implements Disposable { const onWorkspaceRepositoryFileChange = filterEvent(onWorkspaceFileChange, uri => isDescendant(repository.root, uri.fsPath)); const onWorkspaceWorkingTreeFileChange = filterEvent(onWorkspaceRepositoryFileChange, uri => !/\/\.git($|\/)/.test(uri.path)); - const dotGitFileWatcher = new DotGitWatcher(this); + const dotGitFileWatcher = new DotGitWatcher(this, outputChannel); this.disposables.push(dotGitFileWatcher); // FS changes should trigger `git status`: From d978e48bc6ff4b364b661ea0c8d8a7fc53a3927a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 12:36:32 +0200 Subject: [PATCH 330/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8690b7cfbc5a..83d12480989b9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "49ce758993a685b0f621eb6cd9353908ea4eeda4", + "distro": "b7c9b0b730030fb30876d201daa85476c077e57e", "author": { "name": "Microsoft Corporation" }, From 7f365d2ff2522dc9a4ba5b715a36064f75f4f4c7 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 25 Jun 2019 16:36:45 +0200 Subject: [PATCH 331/364] Fix drive letter casing on typescript tasks Occurs when opening by double clicking on workspace file. Fixes #75084 --- extensions/typescript-language-features/src/features/task.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/features/task.ts b/extensions/typescript-language-features/src/features/task.ts index 8c393ade672d5..e366748f725b0 100644 --- a/extensions/typescript-language-features/src/features/task.ts +++ b/extensions/typescript-language-features/src/features/task.ts @@ -234,7 +234,7 @@ class TscTaskProvider implements vscode.TaskProvider { private getLabelForTasks(project: TSConfig): string { if (project.workspaceFolder) { - return path.posix.relative(project.workspaceFolder.uri.path, project.posixPath); + return path.posix.relative(path.posix.normalize(project.workspaceFolder.uri.path), path.posix.normalize(project.posixPath)); } return project.posixPath; } From 50c71bd80733776a17f8f5177c84fb46c460ae15 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 16:59:35 +0200 Subject: [PATCH 332/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83d12480989b9..fc129412f7103 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "b7c9b0b730030fb30876d201daa85476c077e57e", + "distro": "a711cd231d7ec027ffd521d5877fea20a6ca0335", "author": { "name": "Microsoft Corporation" }, From 5d37d79ee12697cdbe5bba9d96dbb418e1437134 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 25 Jun 2019 17:06:07 +0200 Subject: [PATCH 333/364] update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc129412f7103..18b397ee54709 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "a711cd231d7ec027ffd521d5877fea20a6ca0335", + "distro": "1d4ee5533d98dc54e6de1e084a8b6f902c146bfc", "author": { "name": "Microsoft Corporation" }, From 75fed4073fa2b692a2538d6bd47b305975a10196 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 25 Jun 2019 16:12:56 +0200 Subject: [PATCH 334/364] Test remoteName and extensionKind (for #76028) --- .../src/singlefolder-tests/env.test.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts index 31d6d4ce31202..6cfc6f6040845 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/env.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { env } from 'vscode'; +import { env, extensions, ExtensionKind } from 'vscode'; suite('env-namespace', () => { @@ -24,4 +24,22 @@ suite('env-namespace', () => { assert.throws(() => (env as any).sessionId = '234'); }); + test('env.remoteName', function () { + const remoteName = env.remoteName; + const apiTestExtension = extensions.getExtension('vscode.vscode-api-tests'); + const testResolverExtension = extensions.getExtension('vscode.vscode-test-resolver'); + if (typeof remoteName === 'undefined') { + assert.ok(apiTestExtension); + assert.ok(testResolverExtension); + assert.equal(ExtensionKind.UI, apiTestExtension!.extensionKind); + assert.equal(ExtensionKind.UI, testResolverExtension!.extensionKind); + } else if (typeof remoteName === 'string') { + assert.ok(apiTestExtension); + assert.ok(!testResolverExtension); // we currently can only access extensions that run on same host + assert.equal(ExtensionKind.Workspace, apiTestExtension!.extensionKind); + } else { + assert.fail(); + } + }); + }); From 1d851ecfe2b0c36fc5cb15bfeff0176d050f4dc0 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 25 Jun 2019 17:20:41 +0200 Subject: [PATCH 335/364] MainThreadFileSystem does not await --- src/vs/workbench/api/browser/mainThreadFileSystem.ts | 8 ++++---- src/vs/workbench/api/common/extHostFileSystem.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/src/vs/workbench/api/browser/mainThreadFileSystem.ts index 5a52faf060e53..cb84e3c132375 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystem.ts @@ -96,19 +96,19 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { } async $rename(source: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { - this._fileService.move(URI.revive(source), URI.revive(target), opts.overwrite); + await this._fileService.move(URI.revive(source), URI.revive(target), opts.overwrite); } async $copy(source: UriComponents, target: UriComponents, opts: FileOverwriteOptions): Promise { - this._fileService.copy(URI.revive(source), URI.revive(target), opts.overwrite); + await this._fileService.copy(URI.revive(source), URI.revive(target), opts.overwrite); } async $mkdir(uri: UriComponents): Promise { - this._fileService.createFolder(URI.revive(uri)); + await this._fileService.createFolder(URI.revive(uri)); } async $delete(uri: UriComponents, opts: FileDeleteOptions): Promise { - this._fileService.del(URI.revive(uri), opts); + await this._fileService.del(URI.revive(uri), opts); } } diff --git a/src/vs/workbench/api/common/extHostFileSystem.ts b/src/vs/workbench/api/common/extHostFileSystem.ts index 0159b6403ebba..778a5cb67ade2 100644 --- a/src/vs/workbench/api/common/extHostFileSystem.ts +++ b/src/vs/workbench/api/common/extHostFileSystem.ts @@ -124,7 +124,7 @@ class ConsumerFileSystem implements vscode.FileSystem { return this._proxy.$writeFile(uri, VSBuffer.wrap(content), options); } delete(uri: vscode.Uri, options: { recursive: boolean; } = { recursive: false }): Promise { - return this._proxy.$delete(uri, { ...options, useTrash: true }); //todo@joh useTrash + return this._proxy.$delete(uri, { ...options, useTrash: false }); //todo@joh useTrash } rename(oldUri: vscode.Uri, newUri: vscode.Uri, options: { overwrite: boolean; } = { overwrite: false }): Promise { return this._proxy.$rename(oldUri, newUri, options); From 90b3c0ad5b5717c142212141b9bc3d0ec1bca44f Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 25 Jun 2019 09:46:18 -0700 Subject: [PATCH 336/364] Fix #76096 --- src/vs/workbench/api/node/extHostExtensionService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 643f65a6aaf2e..c536032243154 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -562,8 +562,8 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { c(); this._gracefulExit(0); }) - .catch((err) => { - e(err); + .catch((err: Error) => { + e(err.toString()); this._gracefulExit(1); }); } From 3ce04754ad00225a988446efa7b04fb4a2c186f1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 25 Jun 2019 10:53:30 -0700 Subject: [PATCH 337/364] Rename runInBackground to hideFromUser See #75278 --- .../src/singlefolder-tests/window.test.ts | 8 ++++---- src/vs/vscode.d.ts | 2 +- src/vs/vscode.proposed.d.ts | 12 ++++++++++++ .../api/browser/mainThreadTerminalService.ts | 4 ++-- src/vs/workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/node/extHost.api.impl.ts | 1 + src/vs/workbench/api/node/extHostTerminalService.ts | 6 +++--- .../contrib/terminal/browser/terminalService.ts | 4 ++-- src/vs/workbench/contrib/terminal/common/terminal.ts | 2 +- .../contrib/terminal/common/terminalService.ts | 4 ++-- 10 files changed, 29 insertions(+), 16 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts index 321e885acbb87..1918428410859 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/window.test.ts @@ -738,8 +738,8 @@ suite('window namespace tests', () => { terminal1.show(); }); - test('runInBackground terminal: onDidWriteData should work', done => { - const terminal = window.createTerminal({ name: 'bg', runInBackground: true }); + test('hideFromUser terminal: onDidWriteData should work', done => { + const terminal = window.createTerminal({ name: 'bg', hideFromUser: true }); let data = ''; terminal.onDidWriteData(e => { data += e; @@ -751,8 +751,8 @@ suite('window namespace tests', () => { terminal.sendText('foo'); }); - test('runInBackground terminal: should be available to terminals API', done => { - const terminal = window.createTerminal({ name: 'bg', runInBackground: true }); + test('hideFromUser terminal: should be available to terminals API', done => { + const terminal = window.createTerminal({ name: 'bg', hideFromUser: true }); window.onDidOpenTerminal(t => { assert.equal(t, terminal); assert.equal(t.name, 'bg'); diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 953cfb9225952..34cb0b46abb43 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -7042,7 +7042,7 @@ declare module 'vscode' { * interaction is needed. Note that the terminals will still be exposed to all extensions * as normal. */ - runInBackground?: boolean; + hideFromUser?: boolean; } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index f1849eb35e9dd..60b108c952c63 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1121,6 +1121,18 @@ declare module 'vscode' { readonly onDidWriteData: Event; } + + export interface TerminalOptions { + /** + * When enabled the terminal will run the process as normal but not be surfaced to the user + * until `Terminal.show` is called. The typical usage for this is when you need to run + * something that may need interactivity but only want to tell the user about it when + * interaction is needed. Note that the terminals will still be exposed to all extensions + * as normal. + */ + runInBackground?: boolean; + } + /** * Represents the dimensions of a terminal. */ diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index a607cab17b615..f31996419f7a1 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -74,7 +74,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // when the extension host process goes down ? } - public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean, runInBackground?: boolean): Promise<{ id: number, name: string }> { + public $createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string }, waitOnExit?: boolean, strictEnv?: boolean, hideFromUser?: boolean): Promise<{ id: number, name: string }> { const shellLaunchConfig: IShellLaunchConfig = { name, executable: shellPath, @@ -84,7 +84,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape ignoreConfigurationCwd: true, env, strictEnv, - runInBackground + hideFromUser }; const terminal = this._terminalService.createTerminal(shellLaunchConfig); return Promise.resolve({ diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 2de332144235f..2f51c54ee7c4c 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -390,7 +390,7 @@ export interface MainThreadProgressShape extends IDisposable { } export interface MainThreadTerminalServiceShape extends IDisposable { - $createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean, runInBackground?: boolean): Promise<{ id: number, name: string }>; + $createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string, cwd?: string | UriComponents, env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean, hideFromUser?: boolean): Promise<{ id: number, name: string }>; $createTerminalRenderer(name: string): Promise; $dispose(terminalId: number): void; $hide(terminalId: number): void; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 0548192c90340..3ad15b30f7d33 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -524,6 +524,7 @@ export function createApiFactory( }, createTerminal(nameOrOptions?: vscode.TerminalOptions | string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal { if (typeof nameOrOptions === 'object') { + nameOrOptions.hideFromUser = nameOrOptions.hideFromUser || (nameOrOptions.runInBackground && extension.enableProposedApi); return extHostTerminalService.createTerminalFromOptions(nameOrOptions); } return extHostTerminalService.createTerminal(nameOrOptions, shellPath, shellArgs); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index d7432604d4d97..fb3081ff495f2 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -115,9 +115,9 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi env?: { [key: string]: string | null }, waitOnExit?: boolean, strictEnv?: boolean, - runInBackground?: boolean + hideFromUser?: boolean ): void { - this._proxy.$createTerminal(this._name, shellPath, shellArgs, cwd, env, waitOnExit, strictEnv, runInBackground).then(terminal => { + this._proxy.$createTerminal(this._name, shellPath, shellArgs, cwd, env, waitOnExit, strictEnv, hideFromUser).then(terminal => { this._name = terminal.name; this._runQueuedRequests(terminal.id); }); @@ -312,7 +312,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public createTerminalFromOptions(options: vscode.TerminalOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, options.name); - terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv, options.runInBackground); + terminal.create(options.shellPath, options.shellArgs, options.cwd, options.env, /*options.waitOnExit*/ undefined, options.strictEnv, options.hideFromUser); this._terminals.push(terminal); return terminal; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 1e2017721bcc3..1b117021f5357 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -56,7 +56,7 @@ export class TerminalService extends CommonTerminalService implements ITerminalS } public createTerminal(shell: IShellLaunchConfig = {}): ITerminalInstance { - if (shell.runInBackground) { + if (shell.hideFromUser) { const instance = this.createInstance(this._terminalFocusContextKey, this.configHelper, undefined, @@ -86,7 +86,7 @@ export class TerminalService extends CommonTerminalService implements ITerminalS protected _showBackgroundTerminal(instance: ITerminalInstance): void { this._backgroundedTerminalInstances.splice(this._backgroundedTerminalInstances.indexOf(instance), 1); - instance.shellLaunchConfig.runInBackground = false; + instance.shellLaunchConfig.hideFromUser = false; const terminalTab = this._instantiationService.createInstance(TerminalTab, this._terminalFocusContextKey, this.configHelper, diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 7d237e386ed80..af35201e56ae0 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -204,7 +204,7 @@ export interface IShellLaunchConfig { * interaction is needed. Note that the terminals will still be exposed to all extensions * as normal. */ - runInBackground?: boolean; + hideFromUser?: boolean; } export interface ITerminalService { diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 58cca1cbc6ea5..da5d0bcfe4801 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -282,9 +282,9 @@ export abstract class TerminalService implements ITerminalService { } public setActiveInstance(terminalInstance: ITerminalInstance): void { - // If this was a runInBackground terminal created by the API this was triggered by show, + // If this was a hideFromUser terminal created by the API this was triggered by show, // in which case we need to create the terminal tab - if (terminalInstance.shellLaunchConfig.runInBackground) { + if (terminalInstance.shellLaunchConfig.hideFromUser) { this._showBackgroundTerminal(terminalInstance); } this.setActiveInstanceByIndex(this._getIndexFromId(terminalInstance.id)); From 53a1a3506869dbb5530f6b09b5bff990aad8fc02 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 25 Jun 2019 11:42:59 -0700 Subject: [PATCH 338/364] Update distro --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18b397ee54709..c042e80daac38 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.36.0", - "distro": "1d4ee5533d98dc54e6de1e084a8b6f902c146bfc", + "distro": "017ad2e70f6427c6603b82e7d27dd54fa281923d", "author": { "name": "Microsoft Corporation" }, From bd7458a3bd3fbbbe7ad5cfcddc6b4433949e5406 Mon Sep 17 00:00:00 2001 From: Rachel Macfarlane Date: Tue, 25 Jun 2019 13:59:24 -0700 Subject: [PATCH 339/364] Fix minimap decoration rendering on horizontal scroll, fixes #76128 --- src/vs/editor/browser/viewParts/minimap/minimap.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index bb68a3af249cd..a4dd63a650418 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -451,7 +451,7 @@ export class Minimap extends ViewPart { private _options: MinimapOptions; private _lastRenderData: RenderData | null; - private _decorationsChanged: boolean = false; + private _renderDecorations: boolean = false; private _buffers: MinimapBuffers | null; constructor(context: ViewContext) { @@ -650,6 +650,7 @@ export class Minimap extends ViewPart { return true; } public onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean { + this._renderDecorations = true; return true; } public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean { @@ -669,7 +670,7 @@ export class Minimap extends ViewPart { } public onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { - this._decorationsChanged = true; + this._renderDecorations = true; return true; } @@ -720,9 +721,8 @@ export class Minimap extends ViewPart { } private renderDecorations(layout: MinimapLayout) { - const scrollHasChanged = this._lastRenderData && !this._lastRenderData.scrollEquals(layout); - if (scrollHasChanged || this._decorationsChanged) { - this._decorationsChanged = false; + if (this._renderDecorations) { + this._renderDecorations = false; const decorations = this._context.model.getDecorationsInViewport(new Range(layout.startLineNumber, 1, layout.endLineNumber, this._context.model.getLineMaxColumn(layout.endLineNumber))); const { renderMinimap, canvasInnerWidth, canvasInnerHeight } = this._options; @@ -790,11 +790,11 @@ export class Minimap extends ViewPart { const x = lineIndexToXOffset[startColumn - 1]; const width = lineIndexToXOffset[endColumn - 1] - x; - this.renderADecoration(canvasContext, currentDecoration.options.minimap, x, y, width, height); + this.renderDecoration(canvasContext, currentDecoration.options.minimap, x, y, width, height); } } - private renderADecoration(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, x: number, y: number, width: number, height: number) { + private renderDecoration(canvasContext: CanvasRenderingContext2D, minimapOptions: ModelDecorationMinimapOptions, x: number, y: number, width: number, height: number) { const decorationColor = minimapOptions.getColor(this._context.theme); canvasContext.fillStyle = decorationColor; From a55b1545824e427b3461570e35fc9eab36d4c429 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 25 Jun 2019 15:13:54 -0700 Subject: [PATCH 340/364] Handle windows paths correctly when loading webvie resources --- .../contrib/webview/browser/webviewElement.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index 247c1366e728e..a72107be72e66 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -114,8 +114,9 @@ export class IFrameWebview extends Disposable implements Webview { case 'load-resource': { - const uri = URI.file(e.data.data.path); - this.loadResource(uri); + const requestPath = e.data.data.path; + const uri = URI.file(decodeURIComponent(requestPath)); + this.loadResource(requestPath, uri); return; } @@ -301,7 +302,7 @@ export class IFrameWebview extends Disposable implements Webview { this._send('styles', { styles, activeTheme }); } - private async loadResource(uri: URI) { + private async loadResource(requestPath: string, uri: URI) { try { const result = await loadLocalResource(uri, this.fileService, this._options.extension ? this._options.extension.location : undefined, () => (this.content.options.localResourceRoots || [])); @@ -309,7 +310,7 @@ export class IFrameWebview extends Disposable implements Webview { if (result.type === 'success') { return this._send('did-load-resource', { status: 200, - path: uri.path, + path: requestPath, mime: result.mimeType, data: result.data.buffer }); @@ -332,4 +333,3 @@ export class IFrameWebview extends Disposable implements Webview { }); } } - From fa7002641745ef5ce59b522a52c57ce33e4798c5 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 25 Jun 2019 15:32:47 -0700 Subject: [PATCH 341/364] Fix standard link handler for iframe based webviews --- src/vs/workbench/contrib/webview/browser/webviewElement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index a72107be72e66..0c57649c8b639 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -84,7 +84,7 @@ export class IFrameWebview extends Disposable implements Webview { return; case 'did-click-link': - const [uri] = e.data.data; + const uri = e.data.data; this._onDidClickLink.fire(URI.parse(uri)); return; From 53f050c0f37845c81b08094fc10d59fc8d075cc9 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 25 Jun 2019 15:41:10 -0700 Subject: [PATCH 342/364] Mark extensions.all as readonly This iteration, we marked a few other arrays as readonly. We should do the same for extensions.all --- src/vs/vscode.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 34cb0b46abb43..6a886a0e5a7a1 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -8994,7 +8994,7 @@ declare module 'vscode' { /** * All extensions currently known to the system. */ - export let all: Extension[]; + export const all: ReadonlyArray>; /** * An event which fires when `extensions.all` changes. This can happen when extensions are From f4f0afa78acef9069d62202ed82bafdaea5d2426 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 25 Jun 2019 16:15:20 -0700 Subject: [PATCH 343/364] Fix #75927. --- src/vs/editor/browser/viewParts/minimap/minimap.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index a4dd63a650418..f5fb181844b56 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -472,17 +472,18 @@ export class Minimap extends ViewPart { this._shadow.setClassName('minimap-shadow-hidden'); this._domNode.appendChild(this._shadow); - this._canvas = createFastDomNode(document.createElement('canvas')); - this._canvas.setPosition('absolute'); - this._canvas.setLeft(0); - this._domNode.appendChild(this._canvas); - this._decorationsCanvas = createFastDomNode(document.createElement('canvas')); this._decorationsCanvas.setPosition('absolute'); this._decorationsCanvas.setClassName('minimap-decorations-layer'); this._decorationsCanvas.setLeft(0); this._domNode.appendChild(this._decorationsCanvas); + // text are rendered at the top, similar to editor view lines. + this._canvas = createFastDomNode(document.createElement('canvas')); + this._canvas.setPosition('absolute'); + this._canvas.setLeft(0); + this._domNode.appendChild(this._canvas); + this._slider = createFastDomNode(document.createElement('div')); this._slider.setPosition('absolute'); this._slider.setClassName('minimap-slider'); From 6bb4a2530064c4b73de00e5466ca32598b7c1f3f Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 25 Jun 2019 16:19:46 -0700 Subject: [PATCH 344/364] Register mouse down on container dom node. --- src/vs/editor/browser/viewParts/minimap/minimap.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index f5fb181844b56..a8bc3b789e815 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -472,18 +472,17 @@ export class Minimap extends ViewPart { this._shadow.setClassName('minimap-shadow-hidden'); this._domNode.appendChild(this._shadow); + this._canvas = createFastDomNode(document.createElement('canvas')); + this._canvas.setPosition('absolute'); + this._canvas.setLeft(0); + this._domNode.appendChild(this._canvas); + this._decorationsCanvas = createFastDomNode(document.createElement('canvas')); this._decorationsCanvas.setPosition('absolute'); this._decorationsCanvas.setClassName('minimap-decorations-layer'); this._decorationsCanvas.setLeft(0); this._domNode.appendChild(this._decorationsCanvas); - // text are rendered at the top, similar to editor view lines. - this._canvas = createFastDomNode(document.createElement('canvas')); - this._canvas.setPosition('absolute'); - this._canvas.setLeft(0); - this._domNode.appendChild(this._canvas); - this._slider = createFastDomNode(document.createElement('div')); this._slider.setPosition('absolute'); this._slider.setClassName('minimap-slider'); @@ -499,7 +498,7 @@ export class Minimap extends ViewPart { this._applyLayout(); - this._mouseDownListener = dom.addStandardDisposableListener(this._canvas.domNode, 'mousedown', (e) => { + this._mouseDownListener = dom.addStandardDisposableListener(this._domNode.domNode, 'mousedown', (e) => { e.preventDefault(); const renderMinimap = this._options.renderMinimap; From 9670060267d4a44e9c9833bdb23662a8e76041db Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 25 Jun 2019 16:22:13 -0700 Subject: [PATCH 345/364] Make sure we never cancel a request to just one of the ts servers Fixes #76143 --- .../src/tsServer/server.ts | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/tsServer/server.ts b/extensions/typescript-language-features/src/tsServer/server.ts index 9fbe7e80facca..2bcfbf6a9efde 100644 --- a/extensions/typescript-language-features/src/tsServer/server.ts +++ b/extensions/typescript-language-features/src/tsServer/server.ts @@ -357,8 +357,34 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ return this.syntaxServer.executeImpl(command, args, executeInfo); } else if (SyntaxRoutingTsServer.sharedCommands.has(command)) { // Dispatch to both server but only return from syntax one - this.semanticServer.executeImpl(command, args, executeInfo); - return this.syntaxServer.executeImpl(command, args, executeInfo); + + // Also make sure we never cancel requests to just one server + let hasCompletedSyntax = false; + let hasCompletedSemantic = false; + let token: vscode.CancellationToken | undefined = undefined; + if (executeInfo.token) { + const source = new vscode.CancellationTokenSource(); + executeInfo.token.onCancellationRequested(() => { + if (hasCompletedSyntax && !hasCompletedSemantic || hasCompletedSemantic && !hasCompletedSyntax) { + // Don't cancel. + // One of the servers completed this request so we don't want to leave the other + // in a different state + return; + } + source.cancel(); + }); + token = source.token; + } + + const semanticRequest = this.semanticServer.executeImpl(command, args, { ...executeInfo, token }); + if (semanticRequest) { + semanticRequest.finally(() => { hasCompletedSemantic = true; }); + } + const syntaxRequest = this.syntaxServer.executeImpl(command, args, { ...executeInfo, token }); + if (syntaxRequest) { + syntaxRequest.finally(() => { hasCompletedSyntax = true; }); + } + return syntaxRequest; } else { return this.semanticServer.executeImpl(command, args, executeInfo); } From be41fd02a2141ecd0a544b08f51c414a486c4474 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 25 Jun 2019 16:38:38 -0700 Subject: [PATCH 346/364] Show document link tooltip first and put click instructions in parens Fixes #76077 This change also update our standard link hovers to follow this format --- .../src/features/documentLinkProvider.ts | 2 +- src/vs/editor/contrib/links/links.ts | 24 +++++++++---------- src/vs/vscode.d.ts | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/extensions/markdown-language-features/src/features/documentLinkProvider.ts b/extensions/markdown-language-features/src/features/documentLinkProvider.ts index 9ae4bcfed2964..c4344a632bdf4 100644 --- a/extensions/markdown-language-features/src/features/documentLinkProvider.ts +++ b/extensions/markdown-language-features/src/features/documentLinkProvider.ts @@ -39,7 +39,7 @@ function parseLink( return { uri: OpenDocumentLinkCommand.createCommandUri(resourcePath, tempUri.fragment), - tooltip: localize('documentLink.tooltip', 'follow link') + tooltip: localize('documentLink.tooltip', 'Follow link') }; } diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts index ed3b65ef0424e..58f50952234e5 100644 --- a/src/vs/editor/contrib/links/links.ts +++ b/src/vs/editor/contrib/links/links.ts @@ -27,26 +27,26 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic const HOVER_MESSAGE_GENERAL_META = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.navigate.mac', "Cmd + click to follow link") - : nls.localize('links.navigate', "Ctrl + click to follow link") + ? nls.localize('links.navigate.mac', "Follow link (cmd + click)") + : nls.localize('links.navigate', "Follow link (cmd + click)") ); const HOVER_MESSAGE_COMMAND_META = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.command.mac', "Cmd + click to execute command") - : nls.localize('links.command', "Ctrl + click to execute command") + ? nls.localize('links.command.mac', "Execute command (cmd + click)") + : nls.localize('links.command', "Execute command (cmd + click)") ); const HOVER_MESSAGE_GENERAL_ALT = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.navigate.al.mac', "Option + click to follow link") - : nls.localize('links.navigate.al', "Alt + click to follow link") + ? nls.localize('links.navigate.al.mac', "Follow link (cption + click)") + : nls.localize('links.navigate.al', "Follow link (alt + click)") ); const HOVER_MESSAGE_COMMAND_ALT = new MarkdownString().appendText( platform.isMacintosh - ? nls.localize('links.command.al.mac', "Option + click to execute command") - : nls.localize('links.command.al', "Alt + click to execute command") + ? nls.localize('links.command.al.mac', "Execute command (cption + click)") + : nls.localize('links.command.al', "Execute command (alt + click)") ); const decoration = { @@ -116,11 +116,11 @@ class LinkOccurrence { const message = new MarkdownString().appendText( platform.isMacintosh ? useMetaKey - ? nls.localize('links.custom.mac', "Cmd + click to {0}", link.tooltip) - : nls.localize('links.custom.mac.al', "Option + click to {0}", link.tooltip) + ? nls.localize('links.custom.mac', "{0} (cmd + click)", link.tooltip) + : nls.localize('links.custom.mac.al', "{0} (option + click)", link.tooltip) : useMetaKey - ? nls.localize('links.custom', "Ctrl + click to {0}", link.tooltip) - : nls.localize('links.custom.al', "Alt + click to {0}", link.tooltip) + ? nls.localize('links.custom', "{0} (ctrl + click)", link.tooltip) + : nls.localize('links.custom.al', "{0} (alt + click)", link.tooltip) ); options.hoverMessage = message; } diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 6a886a0e5a7a1..d99f3d12f567c 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -3548,7 +3548,7 @@ declare module 'vscode' { * The tooltip text when you hover over this link. * * If a tooltip is provided, is will be displayed in a string that includes instructions on how to - * trigger the link, such as `cmd + click to {0}`. The specific instructions vary depending on OS, + * trigger the link, such as `{0} (ctrl + click)`. The specific instructions vary depending on OS, * user settings, and localization. */ tooltip?: string; From 1e7b87a3206606555a4746fa1ba23129dac30c18 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 25 Jun 2019 16:46:51 -0700 Subject: [PATCH 347/364] reset listener once users choose a dedicated keyboard layout --- src/vs/workbench/services/keybinding/browser/keymapService.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 21546ac6d36bb..c183d82b28a97 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -521,6 +521,7 @@ class BrowserKeymapService extends Disposable implements IKeymapService { BrowserKeyboardMapperFactory.INSTANCE.onKeyboardLayoutChanged(); } else { BrowserKeyboardMapperFactory.INSTANCE.setKeyboardLayout(layout); + this.layoutChangeListener.clear(); } } })); From cc8c1758a5ba86c59ce7c8060364233882589cb6 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 25 Jun 2019 19:29:13 -0700 Subject: [PATCH 348/364] switch to a new layout only when the score is higher. --- .../keybinding/browser/keymapService.ts | 17 +++++++++++++++-- .../services/keybinding/common/keymapInfo.ts | 8 +++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index c183d82b28a97..5de1307f32c4d 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -154,7 +154,20 @@ export class BrowserKeyboardMapperFactoryBase { } setActiveKeyMapping(keymap: IKeyboardMapping | null) { - this._activeKeymapInfo = this.getMatchedKeymapInfo(keymap) || this.getUSStandardLayout(); + let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap); + if (matchedKeyboardLayout) { + if (!this._activeKeymapInfo) { + this._activeKeymapInfo = matchedKeyboardLayout; + } else if (keymap) { + if (matchedKeyboardLayout.getScore(keymap) > this._activeKeymapInfo.getScore(keymap)) { + this._activeKeymapInfo = matchedKeyboardLayout; + } + } + } + + if (!this._activeKeymapInfo) { + this._activeKeymapInfo = this.getUSStandardLayout(); + } if (!this._activeKeymapInfo) { return; @@ -348,7 +361,7 @@ export class BrowserKeyboardMapperFactoryBase { const matchedKeyboardLayout = this.getMatchedKeymapInfo(ret); if (matchedKeyboardLayout) { - return matchedKeyboardLayout.mapping; + return ret; } return null; diff --git a/src/vs/workbench/services/keybinding/common/keymapInfo.ts b/src/vs/workbench/services/keybinding/common/keymapInfo.ts index d0ff2d404694c..edea5fd675c68 100644 --- a/src/vs/workbench/services/keybinding/common/keymapInfo.ts +++ b/src/vs/workbench/services/keybinding/common/keymapInfo.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Event } from 'vs/base/common/event'; -import { isWindows } from 'vs/base/common/platform'; +import { isWindows, isLinux } from 'vs/base/common/platform'; import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { DispatchConfig } from 'vs/workbench/services/keybinding/common/dispatchConfig'; import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper'; @@ -286,6 +286,12 @@ export class KeymapInfo { // keymap from Chromium is probably wrong. continue; } + + if (isLinux && (key === 'Backspace' || key === 'Escape')) { + // native keymap doesn't align with keyboard event + continue; + } + if (this.mapping[key] === undefined) { score -= 1; } From 41691474e5fa22a279d49fc4b58af66bc11ce41b Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Tue, 25 Jun 2019 19:42:47 -0700 Subject: [PATCH 349/364] Fix kb unit test --- src/vs/workbench/services/keybinding/browser/keymapService.ts | 4 ++++ .../services/keybinding/test/browserKeyboardMapper.test.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/keybinding/browser/keymapService.ts b/src/vs/workbench/services/keybinding/browser/keymapService.ts index 5de1307f32c4d..cff794267bf63 100644 --- a/src/vs/workbench/services/keybinding/browser/keymapService.ts +++ b/src/vs/workbench/services/keybinding/browser/keymapService.ts @@ -153,6 +153,10 @@ export class BrowserKeyboardMapperFactoryBase { return this._activeKeymapInfo && keymap && this._activeKeymapInfo.fuzzyEqual(keymap); } + setUSKeyboardLayout() { + this._activeKeymapInfo = this.getUSStandardLayout(); + } + setActiveKeyMapping(keymap: IKeyboardMapping | null) { let matchedKeyboardLayout = this.getMatchedKeymapInfo(keymap); if (matchedKeyboardLayout) { diff --git a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts index 6f817dc867da3..9ea8f70d1e3b1 100644 --- a/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts +++ b/src/vs/workbench/services/keybinding/test/browserKeyboardMapper.test.ts @@ -110,7 +110,7 @@ suite('keyboard layout loader', () => { }, }), true); - TestKeyboardMapperFactory.INSTANCE.setActiveKeyMapping(null); + TestKeyboardMapperFactory.INSTANCE.setUSKeyboardLayout(); assert.equal(TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, true); }); @@ -130,7 +130,7 @@ suite('keyboard layout loader', () => { }, }), true); - TestKeyboardMapperFactory.INSTANCE.setActiveKeyMapping(null); + TestKeyboardMapperFactory.INSTANCE.setUSKeyboardLayout(); assert.equal(TestKeyboardMapperFactory.INSTANCE.activeKeyboardLayout!.isUSStandard, true); }); }); \ No newline at end of file From b0d568409dd971390a7e007554ef2567a97ae197 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 26 Jun 2019 07:56:30 +0200 Subject: [PATCH 350/364] fix #76149 --- .../browser/actions/developerActions.ts | 199 ++++++++++++++++++ .../browser/actions/windowActions.ts | 40 +++- .../workbench/browser/web.simpleservices.ts | 2 + .../electron-browser/remote.contribution.ts | 2 +- .../actions/developerActions.ts | 183 ---------------- .../electron-browser/actions/windowActions.ts | 20 -- .../electron-browser/main.contribution.ts | 14 +- src/vs/workbench/workbench.main.ts | 1 + src/vs/workbench/workbench.web.main.ts | 1 + 9 files changed, 242 insertions(+), 220 deletions(-) create mode 100644 src/vs/workbench/browser/actions/developerActions.ts diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts new file mode 100644 index 0000000000000..60c6f23f2344a --- /dev/null +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -0,0 +1,199 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Action } from 'vs/base/common/actions'; +import { IWindowService } from 'vs/platform/windows/common/windows'; +import * as nls from 'vs/nls'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { domEvent } from 'vs/base/browser/event'; +import { Event } from 'vs/base/common/event'; +import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom'; +import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { timeout } from 'vs/base/common/async'; +import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; + +export class InspectContextKeysAction extends Action { + + static readonly ID = 'workbench.action.inspectContextKeys'; + static LABEL = nls.localize('inspect context keys', "Inspect Context Keys"); + + constructor( + id: string, + label: string, + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IWindowService private readonly windowService: IWindowService, + ) { + super(id, label); + } + + run(): Promise { + const disposables = new DisposableStore(); + + const stylesheet = createStyleSheet(); + disposables.add(toDisposable(() => { + if (stylesheet.parentNode) { + stylesheet.parentNode.removeChild(stylesheet); + } + })); + createCSSRule('*', 'cursor: crosshair !important;', stylesheet); + + const hoverFeedback = document.createElement('div'); + document.body.appendChild(hoverFeedback); + disposables.add(toDisposable(() => document.body.removeChild(hoverFeedback))); + + hoverFeedback.style.position = 'absolute'; + hoverFeedback.style.pointerEvents = 'none'; + hoverFeedback.style.backgroundColor = 'rgba(255, 0, 0, 0.5)'; + hoverFeedback.style.zIndex = '1000'; + + const onMouseMove = domEvent(document.body, 'mousemove', true); + disposables.add(onMouseMove(e => { + const target = e.target as HTMLElement; + const position = getDomNodePagePosition(target); + + hoverFeedback.style.top = `${position.top}px`; + hoverFeedback.style.left = `${position.left}px`; + hoverFeedback.style.width = `${position.width}px`; + hoverFeedback.style.height = `${position.height}px`; + })); + + const onMouseDown = Event.once(domEvent(document.body, 'mousedown', true)); + onMouseDown(e => { e.preventDefault(); e.stopPropagation(); }, null, disposables); + + const onMouseUp = Event.once(domEvent(document.body, 'mouseup', true)); + onMouseUp(e => { + e.preventDefault(); + e.stopPropagation(); + + const context = this.contextKeyService.getContext(e.target as HTMLElement) as Context; + console.log(context.collectAllValues()); + this.windowService.openDevTools(); + + dispose(disposables); + }, null, disposables); + + return Promise.resolve(); + } +} + +export class ToggleScreencastModeAction extends Action { + + static readonly ID = 'workbench.action.toggleScreencastMode'; + static LABEL = nls.localize('toggle screencast mode', "Toggle Screencast Mode"); + + static disposable: IDisposable | undefined; + + constructor( + id: string, + label: string, + @IKeybindingService private readonly keybindingService: IKeybindingService, + @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService + ) { + super(id, label); + } + + async run(): Promise { + if (ToggleScreencastModeAction.disposable) { + ToggleScreencastModeAction.disposable.dispose(); + ToggleScreencastModeAction.disposable = undefined; + return; + } + + const container = this.layoutService.getWorkbenchElement(); + + const mouseMarker = append(container, $('div')); + mouseMarker.style.position = 'absolute'; + mouseMarker.style.border = '2px solid red'; + mouseMarker.style.borderRadius = '20px'; + mouseMarker.style.width = '20px'; + mouseMarker.style.height = '20px'; + mouseMarker.style.top = '0'; + mouseMarker.style.left = '0'; + mouseMarker.style.zIndex = '100000'; + mouseMarker.style.content = ' '; + mouseMarker.style.pointerEvents = 'none'; + mouseMarker.style.display = 'none'; + + const onMouseDown = domEvent(container, 'mousedown', true); + const onMouseUp = domEvent(container, 'mouseup', true); + const onMouseMove = domEvent(container, 'mousemove', true); + + const mouseListener = onMouseDown(e => { + mouseMarker.style.top = `${e.clientY - 10}px`; + mouseMarker.style.left = `${e.clientX - 10}px`; + mouseMarker.style.display = 'block'; + + const mouseMoveListener = onMouseMove(e => { + mouseMarker.style.top = `${e.clientY - 10}px`; + mouseMarker.style.left = `${e.clientX - 10}px`; + }); + + Event.once(onMouseUp)(() => { + mouseMarker.style.display = 'none'; + mouseMoveListener.dispose(); + }); + }); + + const keyboardMarker = append(container, $('div')); + keyboardMarker.style.position = 'absolute'; + keyboardMarker.style.backgroundColor = 'rgba(0, 0, 0 ,0.5)'; + keyboardMarker.style.width = '100%'; + keyboardMarker.style.height = '100px'; + keyboardMarker.style.bottom = '20%'; + keyboardMarker.style.left = '0'; + keyboardMarker.style.zIndex = '100000'; + keyboardMarker.style.pointerEvents = 'none'; + keyboardMarker.style.color = 'white'; + keyboardMarker.style.lineHeight = '100px'; + keyboardMarker.style.textAlign = 'center'; + keyboardMarker.style.fontSize = '56px'; + keyboardMarker.style.display = 'none'; + + const onKeyDown = domEvent(container, 'keydown', true); + let keyboardTimeout: IDisposable = Disposable.None; + + const keyboardListener = onKeyDown(e => { + keyboardTimeout.dispose(); + + const event = new StandardKeyboardEvent(e); + const keybinding = this.keybindingService.resolveKeyboardEvent(event); + const label = keybinding.getLabel(); + + if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { + keyboardMarker.textContent += ' ' + label; + } else { + keyboardMarker.textContent = label; + } + + keyboardMarker.style.display = 'block'; + + const promise = timeout(800); + keyboardTimeout = toDisposable(() => promise.cancel()); + + promise.then(() => { + keyboardMarker.textContent = ''; + keyboardMarker.style.display = 'none'; + }); + }); + + ToggleScreencastModeAction.disposable = toDisposable(() => { + mouseListener.dispose(); + keyboardListener.dispose(); + mouseMarker.remove(); + keyboardMarker.remove(); + }); + } +} + +const developerCategory = nls.localize('developer', "Developer"); +const registry = Registry.as(Extensions.WorkbenchActions); +registry.registerWorkbenchAction(new SyncActionDescriptor(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory); +registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleScreencastModeAction, ToggleScreencastModeAction.ID, ToggleScreencastModeAction.LABEL), 'Developer: Toggle Screencast Mode', developerCategory); diff --git a/src/vs/workbench/browser/actions/windowActions.ts b/src/vs/workbench/browser/actions/windowActions.ts index 744f230607d54..cc2ad1776afc1 100644 --- a/src/vs/workbench/browser/actions/windowActions.ts +++ b/src/vs/workbench/browser/actions/windowActions.ts @@ -9,12 +9,10 @@ import { IWindowService } from 'vs/platform/windows/common/windows'; import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { Registry } from 'vs/platform/registry/common/platform'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import { IsFullscreenContext } from 'vs/workbench/browser/contextkeys'; +import { IsFullscreenContext, IsDevelopmentContext } from 'vs/workbench/browser/contextkeys'; import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; - -const registry = Registry.as(Extensions.WorkbenchActions); -const viewCategory = nls.localize('view', "View"); +import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; export class ToggleFullScreenAction extends Action { @@ -31,12 +29,46 @@ export class ToggleFullScreenAction extends Action { run(): Promise { const container = this.layoutService.getWorkbenchElement(); + return this.windowService.toggleFullScreen(container); } } +export class ReloadWindowAction extends Action { + + static readonly ID = 'workbench.action.reloadWindow'; + static LABEL = nls.localize('reloadWindow', "Reload Window"); + + constructor( + id: string, + label: string, + @IWindowService private readonly windowService: IWindowService + ) { + super(id, label); + } + + async run(): Promise { + await this.windowService.reloadWindow(); + + return true; + } +} + +const registry = Registry.as(Extensions.WorkbenchActions); + +const viewCategory = nls.localize('view', "View"); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleFullScreenAction, ToggleFullScreenAction.ID, ToggleFullScreenAction.LABEL, { primary: KeyCode.F11, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'View: Toggle Full Screen', viewCategory); +const developerCategory = nls.localize('developer', "Developer"); +registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowAction, ReloadWindowAction.ID, ReloadWindowAction.LABEL), 'Developer: Reload Window', developerCategory); + +KeybindingsRegistry.registerKeybindingRule({ + id: ReloadWindowAction.ID, + weight: KeybindingWeight.WorkbenchContrib + 50, + when: IsDevelopmentContext, + primary: KeyMod.CtrlCmd | KeyCode.KEY_R +}); + // Appereance menu MenuRegistry.appendMenuItem(MenuId.MenubarAppearanceMenu, { group: '1_toggle_view', diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 17851c2499490..6df0b784dafe9 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -797,6 +797,8 @@ export class SimpleWindowService extends Disposable implements IWindowService { } reloadWindow(): Promise { + window.location.reload(); + return Promise.resolve(); } diff --git a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts index d211130515b56..78264965a27c0 100644 --- a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts @@ -34,7 +34,7 @@ import { PersistenConnectionEventType } from 'vs/platform/remote/common/remoteAg import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; import Severity from 'vs/base/common/severity'; -import { ReloadWindowAction } from 'vs/workbench/electron-browser/actions/windowActions'; +import { ReloadWindowAction } from 'vs/workbench/browser/actions/windowActions'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { RemoteConnectionState } from 'vs/workbench/browser/contextkeys'; diff --git a/src/vs/workbench/electron-browser/actions/developerActions.ts b/src/vs/workbench/electron-browser/actions/developerActions.ts index 811c9ecac13dd..4da3b429e4827 100644 --- a/src/vs/workbench/electron-browser/actions/developerActions.ts +++ b/src/vs/workbench/electron-browser/actions/developerActions.ts @@ -6,16 +6,6 @@ import { Action } from 'vs/base/common/actions'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; import * as nls from 'vs/nls'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { domEvent } from 'vs/base/browser/event'; -import { Event } from 'vs/base/common/event'; -import { IDisposable, toDisposable, dispose, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { getDomNodePagePosition, createStyleSheet, createCSSRule, append, $ } from 'vs/base/browser/dom'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { Context } from 'vs/platform/contextkey/browser/contextKeyService'; -import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { timeout } from 'vs/base/common/async'; -import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; export class ToggleDevToolsAction extends Action { @@ -44,176 +34,3 @@ export class ToggleSharedProcessAction extends Action { return this.windowsService.toggleSharedProcess(); } } - -export class InspectContextKeysAction extends Action { - - static readonly ID = 'workbench.action.inspectContextKeys'; - static LABEL = nls.localize('inspect context keys', "Inspect Context Keys"); - - constructor( - id: string, - label: string, - @IContextKeyService private readonly contextKeyService: IContextKeyService, - @IWindowService private readonly windowService: IWindowService, - ) { - super(id, label); - } - - run(): Promise { - const disposables = new DisposableStore(); - - const stylesheet = createStyleSheet(); - disposables.add(toDisposable(() => { - if (stylesheet.parentNode) { - stylesheet.parentNode.removeChild(stylesheet); - } - })); - createCSSRule('*', 'cursor: crosshair !important;', stylesheet); - - const hoverFeedback = document.createElement('div'); - document.body.appendChild(hoverFeedback); - disposables.add(toDisposable(() => document.body.removeChild(hoverFeedback))); - - hoverFeedback.style.position = 'absolute'; - hoverFeedback.style.pointerEvents = 'none'; - hoverFeedback.style.backgroundColor = 'rgba(255, 0, 0, 0.5)'; - hoverFeedback.style.zIndex = '1000'; - - const onMouseMove = domEvent(document.body, 'mousemove', true); - disposables.add(onMouseMove(e => { - const target = e.target as HTMLElement; - const position = getDomNodePagePosition(target); - - hoverFeedback.style.top = `${position.top}px`; - hoverFeedback.style.left = `${position.left}px`; - hoverFeedback.style.width = `${position.width}px`; - hoverFeedback.style.height = `${position.height}px`; - })); - - const onMouseDown = Event.once(domEvent(document.body, 'mousedown', true)); - onMouseDown(e => { e.preventDefault(); e.stopPropagation(); }, null, disposables); - - const onMouseUp = Event.once(domEvent(document.body, 'mouseup', true)); - onMouseUp(e => { - e.preventDefault(); - e.stopPropagation(); - - const context = this.contextKeyService.getContext(e.target as HTMLElement) as Context; - console.log(context.collectAllValues()); - this.windowService.openDevTools(); - - dispose(disposables); - }, null, disposables); - - return Promise.resolve(); - } -} - -export class ToggleScreencastModeAction extends Action { - - static readonly ID = 'workbench.action.toggleScreencastMode'; - static LABEL = nls.localize('toggle screencast mode', "Toggle Screencast Mode"); - - static disposable: IDisposable | undefined; - - constructor( - id: string, - label: string, - @IKeybindingService private readonly keybindingService: IKeybindingService, - @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService - ) { - super(id, label); - } - - async run(): Promise { - if (ToggleScreencastModeAction.disposable) { - ToggleScreencastModeAction.disposable.dispose(); - ToggleScreencastModeAction.disposable = undefined; - return; - } - - const container = this.layoutService.getWorkbenchElement(); - - const mouseMarker = append(container, $('div')); - mouseMarker.style.position = 'absolute'; - mouseMarker.style.border = '2px solid red'; - mouseMarker.style.borderRadius = '20px'; - mouseMarker.style.width = '20px'; - mouseMarker.style.height = '20px'; - mouseMarker.style.top = '0'; - mouseMarker.style.left = '0'; - mouseMarker.style.zIndex = '100000'; - mouseMarker.style.content = ' '; - mouseMarker.style.pointerEvents = 'none'; - mouseMarker.style.display = 'none'; - - const onMouseDown = domEvent(container, 'mousedown', true); - const onMouseUp = domEvent(container, 'mouseup', true); - const onMouseMove = domEvent(container, 'mousemove', true); - - const mouseListener = onMouseDown(e => { - mouseMarker.style.top = `${e.clientY - 10}px`; - mouseMarker.style.left = `${e.clientX - 10}px`; - mouseMarker.style.display = 'block'; - - const mouseMoveListener = onMouseMove(e => { - mouseMarker.style.top = `${e.clientY - 10}px`; - mouseMarker.style.left = `${e.clientX - 10}px`; - }); - - Event.once(onMouseUp)(() => { - mouseMarker.style.display = 'none'; - mouseMoveListener.dispose(); - }); - }); - - const keyboardMarker = append(container, $('div')); - keyboardMarker.style.position = 'absolute'; - keyboardMarker.style.backgroundColor = 'rgba(0, 0, 0 ,0.5)'; - keyboardMarker.style.width = '100%'; - keyboardMarker.style.height = '100px'; - keyboardMarker.style.bottom = '20%'; - keyboardMarker.style.left = '0'; - keyboardMarker.style.zIndex = '100000'; - keyboardMarker.style.pointerEvents = 'none'; - keyboardMarker.style.color = 'white'; - keyboardMarker.style.lineHeight = '100px'; - keyboardMarker.style.textAlign = 'center'; - keyboardMarker.style.fontSize = '56px'; - keyboardMarker.style.display = 'none'; - - const onKeyDown = domEvent(container, 'keydown', true); - let keyboardTimeout: IDisposable = Disposable.None; - - const keyboardListener = onKeyDown(e => { - keyboardTimeout.dispose(); - - const event = new StandardKeyboardEvent(e); - const keybinding = this.keybindingService.resolveKeyboardEvent(event); - const label = keybinding.getLabel(); - - if (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && this.keybindingService.mightProducePrintableCharacter(event) && label) { - keyboardMarker.textContent += ' ' + label; - } else { - keyboardMarker.textContent = label; - } - - keyboardMarker.style.display = 'block'; - - const promise = timeout(800); - keyboardTimeout = toDisposable(() => promise.cancel()); - - promise.then(() => { - keyboardMarker.textContent = ''; - keyboardMarker.style.display = 'none'; - }); - }); - - ToggleScreencastModeAction.disposable = toDisposable(() => { - mouseListener.dispose(); - keyboardListener.dispose(); - mouseMarker.remove(); - keyboardMarker.remove(); - }); - } -} diff --git a/src/vs/workbench/electron-browser/actions/windowActions.ts b/src/vs/workbench/electron-browser/actions/windowActions.ts index 1277463c355df..58b52edeb5133 100644 --- a/src/vs/workbench/electron-browser/actions/windowActions.ts +++ b/src/vs/workbench/electron-browser/actions/windowActions.ts @@ -150,26 +150,6 @@ export class ZoomResetAction extends BaseZoomAction { } } -export class ReloadWindowAction extends Action { - - static readonly ID = 'workbench.action.reloadWindow'; - static LABEL = nls.localize('reloadWindow', "Reload Window"); - - constructor( - id: string, - label: string, - @IWindowService private readonly windowService: IWindowService - ) { - super(id, label); - } - - async run(): Promise { - await this.windowService.reloadWindow(); - - return true; - } -} - export class ReloadWindowWithExtensionsDisabledAction extends Action { static readonly ID = 'workbench.action.reloadWindowWithExtensionsDisabled'; diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index e6adc96847a35..9d2b119c09132 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -12,8 +12,8 @@ import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/action import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { isWindows, isLinux, isMacintosh } from 'vs/base/common/platform'; import { KeybindingsReferenceAction, OpenDocumentationUrlAction, OpenIntroductoryVideosUrlAction, OpenTipsAndTricksUrlAction, OpenTwitterUrlAction, OpenRequestFeatureUrlAction, OpenPrivacyStatementUrlAction, OpenLicenseUrlAction, OpenNewsletterSignupUrlAction } from 'vs/workbench/electron-browser/actions/helpActions'; -import { ToggleSharedProcessAction, InspectContextKeysAction, ToggleScreencastModeAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; -import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ReloadWindowAction, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; +import { ToggleSharedProcessAction, ToggleDevToolsAction } from 'vs/workbench/electron-browser/actions/developerActions'; +import { ShowAboutDialogAction, ZoomResetAction, ZoomOutAction, ZoomInAction, CloseCurrentWindowAction, SwitchWindow, NewWindowAction, QuickSwitchWindow, QuickOpenRecentAction, inRecentFilesPickerContextKey, OpenRecentAction, ReloadWindowWithExtensionsDisabledAction, NewWindowTabHandler, ShowPreviousWindowTabHandler, ShowNextWindowTabHandler, MoveWindowTabToNewWindowHandler, MergeWindowTabsHandlerHandler, ToggleWindowTabsBarHandler } from 'vs/workbench/electron-browser/actions/windowActions'; import { AddRootFolderAction, GlobalRemoveRootFolderAction, SaveWorkspaceAsAction, OpenWorkspaceConfigFileAction, DuplicateWorkspaceInNewWindowAction, CloseWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { inQuickOpenContext, getQuickNavigateHandler } from 'vs/workbench/browser/parts/quickopen/quickopen'; @@ -149,20 +149,10 @@ import product from 'vs/platform/product/node/product'; (function registerDeveloperActions(): void { const developerCategory = nls.localize('developer', "Developer"); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleSharedProcessAction, ToggleSharedProcessAction.ID, ToggleSharedProcessAction.LABEL), 'Developer: Toggle Shared Process', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(InspectContextKeysAction, InspectContextKeysAction.ID, InspectContextKeysAction.LABEL), 'Developer: Inspect Context Keys', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleScreencastModeAction, ToggleScreencastModeAction.ID, ToggleScreencastModeAction.LABEL), 'Developer: Toggle Screencast Mode', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowWithExtensionsDisabledAction, ReloadWindowWithExtensionsDisabledAction.ID, ReloadWindowWithExtensionsDisabledAction.LABEL), 'Developer: Reload Window With Extensions Disabled', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(LogStorageAction, LogStorageAction.ID, LogStorageAction.LABEL), 'Developer: Log Storage Database Contents', developerCategory); - registry.registerWorkbenchAction(new SyncActionDescriptor(ReloadWindowAction, ReloadWindowAction.ID, ReloadWindowAction.LABEL), 'Developer: Reload Window', developerCategory); registry.registerWorkbenchAction(new SyncActionDescriptor(ToggleDevToolsAction, ToggleDevToolsAction.ID, ToggleDevToolsAction.LABEL), 'Developer: Toggle Developer Tools', developerCategory); - KeybindingsRegistry.registerKeybindingRule({ - id: ReloadWindowAction.ID, - weight: KeybindingWeight.WorkbenchContrib + 50, - when: IsDevelopmentContext, - primary: KeyMod.CtrlCmd | KeyCode.KEY_R - }); - KeybindingsRegistry.registerKeybindingRule({ id: ToggleDevToolsAction.ID, weight: KeybindingWeight.WorkbenchContrib + 50, diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 1175acef2f52b..8535066a63b68 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -21,6 +21,7 @@ import 'vs/workbench/electron-browser/main'; import 'vs/workbench/browser/actions/layoutActions'; import 'vs/workbench/browser/actions/windowActions'; +import 'vs/workbench/browser/actions/developerActions'; import 'vs/workbench/browser/actions/listCommands'; import 'vs/workbench/browser/actions/navigationActions'; import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 456e293452b54..c28adc0ad98a6 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -20,6 +20,7 @@ import 'vs/workbench/browser/web.main'; import 'vs/workbench/browser/actions/layoutActions'; import 'vs/workbench/browser/actions/windowActions'; +import 'vs/workbench/browser/actions/developerActions'; import 'vs/workbench/browser/actions/listCommands'; import 'vs/workbench/browser/actions/navigationActions'; import 'vs/workbench/browser/parts/quickopen/quickOpenActions'; From f9587710deadfdef6a03b5a7492e9056c2f72235 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 26 Jun 2019 07:56:41 +0200 Subject: [PATCH 351/364] web - document some API --- src/vs/workbench/workbench.web.api.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index d8070d0ce4c01..30d2fd8b79b0b 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -9,13 +9,33 @@ import { UriComponents } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; export interface IWorkbenchConstructionOptions { + + /** + * Experimental: the remote authority is the IP:PORT from where the workbench is served + * from. It is for example being used for the websocket connections as address. + */ remoteAuthority: string; + /** + * Experimental: An endpoint to serve iframe content ("webview") from. This is required + * to provide full security isolation from the workbench host. + */ webviewEndpoint?: string; + /** + * Experimental: An optional folder that is set as workspace context for the workbench. + */ folderUri?: UriComponents; + + /** + * Experimental: An optional workspace that is set as workspace context for the workbench. + */ workspaceUri?: UriComponents; + /** + * Experimental: The userData namespace is used to handle user specific application + * data like settings, keybindings, UI state and snippets. + */ userData?: { read(key: string): Promise; write(key: string, value: string): Promise; @@ -23,6 +43,12 @@ export interface IWorkbenchConstructionOptions { }; } +/** + * Experimental: Creates the workbench with the provided options in the provided container. + * + * @param domElement the container to create the workbench in + * @param options for setting up the workbench + */ function create(domElement: HTMLElement, options: IWorkbenchConstructionOptions): Promise { return main(domElement, options); } From 30b6b2e992971e8687b139ed5d3dd63b8e86fea9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 26 Jun 2019 08:32:36 +0200 Subject: [PATCH 352/364] :lipstick: workbench API --- src/vs/workbench/workbench.web.api.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 30d2fd8b79b0b..1fda1a6becab7 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -7,6 +7,7 @@ import 'vs/workbench/workbench.web.main'; import { main } from 'vs/workbench/browser/web.main'; import { UriComponents } from 'vs/base/common/uri'; import { Event } from 'vs/base/common/event'; +import { VSBuffer } from 'vs/base/common/buffer'; export interface IWorkbenchConstructionOptions { @@ -36,10 +37,15 @@ export interface IWorkbenchConstructionOptions { * Experimental: The userData namespace is used to handle user specific application * data like settings, keybindings, UI state and snippets. */ - userData?: { - read(key: string): Promise; - write(key: string, value: string): Promise; - onDidChange: Event; + userDataProvider?: { + readonly onDidChangeFile: Event; + + readFile(path: string): Promise; + readDirectory(path: string): Promise; + + writeFile(path: string, content: VSBuffer): Promise; + + delete(path: string): Promise; }; } From 86306cce8a7bf5320b7d320196401b39bb8835a1 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 26 Jun 2019 11:06:41 +0200 Subject: [PATCH 353/364] disable arm and alpine for stable fixes #76159 --- build/azure-pipelines/product-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 60d99b36ed4c3..85de2d3f35154 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -51,7 +51,7 @@ jobs: - template: linux/snap-build-linux.yml - job: LinuxArmhf - condition: eq(variables['VSCODE_BUILD_LINUX_ARMHF'], 'true') + condition: and(eq(variables['VSCODE_BUILD_LINUX_ARMHF'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' @@ -61,7 +61,7 @@ jobs: - template: linux/product-build-linux-arm.yml - job: LinuxAlpine - condition: eq(variables['VSCODE_BUILD_LINUX_ALPINE'], 'true') + condition: and(eq(variables['VSCODE_BUILD_LINUX_ALPINE'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable'))) timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' From b266566c3b65f500c26588049a010a11123a1686 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 26 Jun 2019 11:11:56 +0200 Subject: [PATCH 354/364] Fix extra auto complete on fast delete (#74675) Fixes #vscode-remote-release/4 --- .../dialogs/browser/remoteFileDialog.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts index 6a3b741424e4f..0ae7ef8a5961f 100644 --- a/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts +++ b/src/vs/workbench/services/dialogs/browser/remoteFileDialog.ts @@ -331,6 +331,7 @@ export class RemoteFileDialog { } } else { this.filePickBox.activeItems = []; + this.userEnteredPathSegment = ''; } } } catch { @@ -369,7 +370,11 @@ export class RemoteFileDialog { } private constructFullUserPath(): string { - return this.pathAppend(this.currentFolder, this.userEnteredPathSegment); + if (equalsIgnoreCase(this.filePickBox.value.substr(0, this.userEnteredPathSegment.length), this.userEnteredPathSegment)) { + return this.pathFromUri(this.currentFolder); + } else { + return this.pathAppend(this.currentFolder, this.userEnteredPathSegment); + } } private filePickBoxValue(): URI { @@ -492,11 +497,13 @@ export class RemoteFileDialog { const userPath = this.constructFullUserPath(); if (equalsIgnoreCase(userPath, value.substring(0, userPath.length))) { let hasMatch = false; - for (let i = 0; i < this.filePickBox.items.length; i++) { - const item = this.filePickBox.items[i]; - if (this.setAutoComplete(value, inputBasename, item)) { - hasMatch = true; - break; + if (inputBasename.length > this.userEnteredPathSegment.length) { + for (let i = 0; i < this.filePickBox.items.length; i++) { + const item = this.filePickBox.items[i]; + if (this.setAutoComplete(value, inputBasename, item)) { + hasMatch = true; + break; + } } } if (!hasMatch) { @@ -505,11 +512,7 @@ export class RemoteFileDialog { this.filePickBox.activeItems = []; } } else { - if (!equalsIgnoreCase(inputBasename, resources.basename(this.currentFolder))) { - this.userEnteredPathSegment = inputBasename; - } else { - this.userEnteredPathSegment = ''; - } + this.userEnteredPathSegment = inputBasename; this.autoCompletePathSegment = ''; } } From f15e5a706bc6bb756d3ae66a422baf188aefdb78 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 26 Jun 2019 11:17:26 +0200 Subject: [PATCH 355/364] use yarn --frozen-lockfile for builds --- build/azure-pipelines/darwin/continuous-build-darwin.yml | 2 +- build/azure-pipelines/darwin/product-build-darwin.yml | 2 +- build/azure-pipelines/linux/continuous-build-linux.yml | 2 +- .../azure-pipelines/linux/product-build-linux-alpine.yml | 2 +- build/azure-pipelines/linux/product-build-linux-arm.yml | 2 +- build/azure-pipelines/linux/product-build-linux.yml | 2 +- build/azure-pipelines/win32/continuous-build-win32.yml | 2 +- build/azure-pipelines/win32/product-build-win32.yml | 2 +- build/npm/postinstall.js | 9 +++------ 9 files changed, 11 insertions(+), 14 deletions(-) diff --git a/build/azure-pipelines/darwin/continuous-build-darwin.yml b/build/azure-pipelines/darwin/continuous-build-darwin.yml index 776c1172beabb..d84beb2e597ed 100644 --- a/build/azure-pipelines/darwin/continuous-build-darwin.yml +++ b/build/azure-pipelines/darwin/continuous-build-darwin.yml @@ -11,7 +11,7 @@ steps: inputs: versionSpec: "1.10.1" - script: | - yarn + yarn --frozen-lockfile displayName: Install Dependencies condition: ne(variables['CacheRestored'], 'true') - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index 0b9a362c07587..5cb5d7243d200 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -37,7 +37,7 @@ steps: - script: | set -e - yarn + yarn --frozen-lockfile displayName: Install dependencies - script: | diff --git a/build/azure-pipelines/linux/continuous-build-linux.yml b/build/azure-pipelines/linux/continuous-build-linux.yml index ee47a8d432099..bce42a665fe96 100644 --- a/build/azure-pipelines/linux/continuous-build-linux.yml +++ b/build/azure-pipelines/linux/continuous-build-linux.yml @@ -19,7 +19,7 @@ steps: inputs: versionSpec: "1.10.1" - script: | - yarn + yarn --frozen-lockfile displayName: Install Dependencies condition: ne(variables['CacheRestored'], 'true') - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 diff --git a/build/azure-pipelines/linux/product-build-linux-alpine.yml b/build/azure-pipelines/linux/product-build-linux-alpine.yml index 107f7fa0cec73..5bce791dcf64a 100644 --- a/build/azure-pipelines/linux/product-build-linux-alpine.yml +++ b/build/azure-pipelines/linux/product-build-linux-alpine.yml @@ -46,7 +46,7 @@ steps: - script: | set -e - CHILD_CONCURRENCY=1 yarn + CHILD_CONCURRENCY=1 yarn --frozen-lockfile displayName: Install dependencies - script: | diff --git a/build/azure-pipelines/linux/product-build-linux-arm.yml b/build/azure-pipelines/linux/product-build-linux-arm.yml index ffa6d18f68e9d..6aac72535bc93 100644 --- a/build/azure-pipelines/linux/product-build-linux-arm.yml +++ b/build/azure-pipelines/linux/product-build-linux-arm.yml @@ -46,7 +46,7 @@ steps: - script: | set -e - CHILD_CONCURRENCY=1 yarn + CHILD_CONCURRENCY=1 yarn --frozen-lockfile displayName: Install dependencies - script: | diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 210798a47761c..a93dd8edd0dbd 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -38,7 +38,7 @@ steps: - script: | set -e - CHILD_CONCURRENCY=1 yarn + CHILD_CONCURRENCY=1 yarn --frozen-lockfile displayName: Install dependencies - script: | diff --git a/build/azure-pipelines/win32/continuous-build-win32.yml b/build/azure-pipelines/win32/continuous-build-win32.yml index 36336276814a5..85d648e8f41d6 100644 --- a/build/azure-pipelines/win32/continuous-build-win32.yml +++ b/build/azure-pipelines/win32/continuous-build-win32.yml @@ -15,7 +15,7 @@ steps: targetfolder: '**/node_modules, !**/node_modules/**/node_modules' vstsFeed: '$(ArtifactFeed)' - powershell: | - yarn + yarn --frozen-lockfile displayName: Install Dependencies condition: ne(variables['CacheRestored'], 'true') - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 6efaa050dcc71..06c6342b81eff 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -40,7 +40,7 @@ steps: $ErrorActionPreference = "Stop" $env:npm_config_arch="$(VSCODE_ARCH)" $env:CHILD_CONCURRENCY="1" - exec { yarn } + exec { yarn --frozen-lockfile } displayName: Install dependencies - powershell: | diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index edc5e35ade350..80a4f0eeb5c3c 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -20,13 +20,10 @@ function yarnInstall(location, opts) { const raw = process.env['npm_config_argv'] || '{}'; const argv = JSON.parse(raw); const original = argv.original || []; - const args = ['install']; + const args = original.filter(arg => arg === '--ignore-optional' || arg === '--frozen-lockfile'); - if (original.indexOf('--ignore-optional') > -1) { - args.push('--ignore-optional'); - } - - console.log('Installing dependencies in \'%s\'.', location); + console.log(`Installing dependencies in ${location}...`); + console.log(`$ yarn ${args.join(' ')}`); const result = cp.spawnSync(yarn, args, opts); if (result.error || result.status !== 0) { From aae636e246a90f3ceeb8a96986cafacaab89fc27 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 26 Jun 2019 11:19:19 +0200 Subject: [PATCH 356/364] remove `update.enableWindowsBackgroundUpdates` from online settings --- src/vs/platform/update/node/update.config.contribution.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/platform/update/node/update.config.contribution.ts b/src/vs/platform/update/node/update.config.contribution.ts index 26e63ea0fe81b..b6ef43b29fa54 100644 --- a/src/vs/platform/update/node/update.config.contribution.ts +++ b/src/vs/platform/update/node/update.config.contribution.ts @@ -41,7 +41,6 @@ configurationRegistry.registerConfiguration({ scope: ConfigurationScope.APPLICATION, title: localize('enableWindowsBackgroundUpdatesTitle', "Enable Background Updates on Windows"), description: localize('enableWindowsBackgroundUpdates', "Enable to download and install new VS Code Versions in the background on Windows"), - tags: ['usesOnlineServices'], included: isWindows }, 'update.showReleaseNotes': { From d52846203f9f7db0626188ae50934f098b943897 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 26 Jun 2019 11:24:42 +0200 Subject: [PATCH 357/364] fix #76076 --- src/vs/base/common/buffer.ts | 7 +++- .../base/test/{common => node}/buffer.test.ts | 38 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) rename src/vs/base/test/{common => node}/buffer.test.ts (90%) diff --git a/src/vs/base/common/buffer.ts b/src/vs/base/common/buffer.ts index cf34296e74c28..7b4e9cc8d6686 100644 --- a/src/vs/base/common/buffer.ts +++ b/src/vs/base/common/buffer.ts @@ -78,7 +78,10 @@ export class VSBuffer { } slice(start?: number, end?: number): VSBuffer { - return new VSBuffer(this.buffer.slice(start, end)); + // IMPORTANT: use subarray instead of slice because TypedArray#slice + // creates shallow copy and NodeBuffer#slice doesn't. The use of subarray + // ensures the same, performant, behaviour. + return new VSBuffer(this.buffer.subarray(start!/*bad lib.d.ts*/, end)); } set(array: VSBuffer, offset?: number): void { @@ -437,4 +440,4 @@ class VSBufferWriteableStreamImpl implements VSBufferWriteableStream { this.listeners.end.length = 0; } } -} \ No newline at end of file +} diff --git a/src/vs/base/test/common/buffer.test.ts b/src/vs/base/test/node/buffer.test.ts similarity index 90% rename from src/vs/base/test/common/buffer.test.ts rename to src/vs/base/test/node/buffer.test.ts index c5a3cd676eefa..65f84a66ddf72 100644 --- a/src/vs/base/test/common/buffer.test.ts +++ b/src/vs/base/test/node/buffer.test.ts @@ -364,4 +364,42 @@ suite('Buffer', () => { assert.equal(ended, false); assert.equal(errors.length, 0); }); + + test('Performance issue with VSBuffer#slice #76076', function () { + // Buffer#slice creates a view + { + const buff = Buffer.from([10, 20, 30, 40]); + const b2 = buff.slice(1, 3); + assert.equal(buff[1], 20); + assert.equal(b2[0], 20); + + buff[1] = 17; // modify buff AND b2 + assert.equal(buff[1], 17); + assert.equal(b2[0], 17); + } + + // TypedArray#slice creates a copy + { + const unit = new Uint8Array([10, 20, 30, 40]); + const u2 = unit.slice(1, 3); + assert.equal(unit[1], 20); + assert.equal(u2[0], 20); + + unit[1] = 17; // modify unit, NOT b2 + assert.equal(unit[1], 17); + assert.equal(u2[0], 20); + } + + // TypedArray#subarray creates a view + { + const unit = new Uint8Array([10, 20, 30, 40]); + const u2 = unit.subarray(1, 3); + assert.equal(unit[1], 20); + assert.equal(u2[0], 20); + + unit[1] = 17; // modify unit AND b2 + assert.equal(unit[1], 17); + assert.equal(u2[0], 17); + } + }); }); From d67b5df66803918e9f098db0693c8c6340c6aed2 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 26 Jun 2019 11:48:06 +0200 Subject: [PATCH 358/364] revert the change --- product.json | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/product.json b/product.json index 8037965bff05f..4103352af85f3 100644 --- a/product.json +++ b/product.json @@ -22,12 +22,5 @@ "urlProtocol": "code-oss", "extensionAllowedProposedApi": [ "ms-vscode.references-view" - ], - "extensionsGallery": { - "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery", - "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index", - "itemUrl": "https://marketplace.visualstudio.com/items", - "controlUrl": "https://az764295.vo.msecnd.net/extensions/marketplace.json", - "recommendationsUrl": "https://az764295.vo.msecnd.net/extensions/workspaceRecommendations.json.gz" - } + ] } \ No newline at end of file From ffed70a39967c0d067e48873a36982448cb3e4fb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 26 Jun 2019 12:40:53 +0200 Subject: [PATCH 359/364] prevent product.json containing gallery --- build/gulpfile.hygiene.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 5008269333453..a66723ec7e4a3 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -175,6 +175,17 @@ gulp.task('tslint', () => { function hygiene(some) { let errorCount = 0; + const productJson = es.through(function (file) { + const product = JSON.parse(file.contents.toString('utf8')); + + if (product.extensionsGallery) { + console.error('product.json: Contains "extensionsGallery"'); + errorCount++; + } + + this.emit('data', file); + }); + const indentation = es.through(function (file) { const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/); file.__lines = lines; @@ -258,8 +269,13 @@ function hygiene(some) { input = some; } + const productJsonFilter = filter('product.json', { restore: true }); + const result = input .pipe(filter(f => !f.stat.isDirectory())) + .pipe(productJsonFilter) + .pipe(productJson) + .pipe(productJsonFilter.restore) .pipe(filter(indentationFilter)) .pipe(indentation) .pipe(filter(copyrightFilter)) From 66dd9c69db7b3565b5618f77ebac38f1e01ac8d5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 26 Jun 2019 14:01:06 +0200 Subject: [PATCH 360/364] fix #76074 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index 12d9ee5b662fe..dbfe7f496354c 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -628,7 +628,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); KeybindingsRegistry.registerCommandAndKeybindingRule({ - id: 'breadcrumbs.focusPrevious', + id: 'breadcrumbs.focusPreviousWithPicker', weight: KeybindingWeight.WorkbenchContrib + 1, primary: KeyMod.CtrlCmd | KeyCode.LeftArrow, mac: { From d30e71f75f801c7b741a0a19c488812c63f9bb9c Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 26 Jun 2019 14:15:02 +0200 Subject: [PATCH 361/364] fixes #54084 --- src/vs/workbench/contrib/debug/browser/debug.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 88b7066084845..e54b4d4e5d4d8 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -539,7 +539,7 @@ if (isMacintosh) { command: { id, title, - iconLocation: { dark: URI.parse(require.toUrl(`vs/workbench/contrib/debug/electron-browser/media/${icon}`)) } + iconLocation: { dark: URI.parse(require.toUrl(`vs/workbench/contrib/debug/browser/media/${icon}`)) } }, when, group: '9_debug', From d0c362792aa27ae6b6648f8b99d8d78e6095d537 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 26 Jun 2019 14:24:23 +0200 Subject: [PATCH 362/364] Fix #76105 --- .../extensions/node/extensionsWorkbenchService.ts | 2 +- .../electron-browser/remoteExtensionManagementIpc.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts index d91ddb528821f..a332c2733bb4c 100644 --- a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts @@ -861,7 +861,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension this.queryGallery({ names, ids, pageSize: 1 }, CancellationToken.None); } finally { this.installing = this.installing.filter(e => e !== extension); - this._onChange.fire(extension); + this._onChange.fire(this.local.filter(e => areSameExtensions(e.identifier, extension.identifier))[0]); } } diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts index 0879eb39178ee..6fd6dc821e80b 100644 --- a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -70,10 +70,12 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC if (!compatible) { return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version))); } - const local = await this.downloadAndInstall(extension, installed); - const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(local.manifest, CancellationToken.None); - await Promise.all(workspaceExtensions.map(e => this.downloadAndInstall(e, installed))); - return local; + const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None); + if (manifest) { + const workspaceExtensions = await this.getAllWorkspaceDependenciesAndPackedExtensions(manifest, CancellationToken.None); + await Promise.all(workspaceExtensions.map(e => this.downloadAndInstall(e, installed))); + } + return this.downloadAndInstall(extension, installed); } private async downloadAndInstall(extension: IGalleryExtension, installed: ILocalExtension[]): Promise { From 56af1b0a07df07aa2efa70aceac570aeade7c72f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 26 Jun 2019 14:54:34 +0200 Subject: [PATCH 363/364] fix #75904 --- src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts index dbfe7f496354c..1ca86d594052d 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts @@ -704,7 +704,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ handler(accessor) { const editors = accessor.get(IEditorService); const lists = accessor.get(IListService); - const element = lists.lastFocusedList ? lists.lastFocusedList.getFocus() : undefined; + const element = lists.lastFocusedList ? lists.lastFocusedList.getFocus()[0] : undefined; if (element instanceof OutlineElement) { const outlineElement = OutlineModel.get(element); if (!outlineElement) { From 6507e4272c3c3fae935f73a4a608a0ccd6e1a927 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 26 Jun 2019 15:06:51 +0200 Subject: [PATCH 364/364] workaround for #74934 --- src/vs/editor/contrib/documentSymbols/outlineTree.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/documentSymbols/outlineTree.ts b/src/vs/editor/contrib/documentSymbols/outlineTree.ts index dc34e90fcfbdd..a24e8cd4d3956 100644 --- a/src/vs/editor/contrib/documentSymbols/outlineTree.ts +++ b/src/vs/editor/contrib/documentSymbols/outlineTree.ts @@ -22,6 +22,7 @@ import { OutlineConfigKeys } from 'vs/editor/contrib/documentSymbols/outline'; import { MarkerSeverity } from 'vs/platform/markers/common/markers'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { listErrorForeground, listWarningForeground } from 'vs/platform/theme/common/colorRegistry'; +import { KeyCode } from 'vs/base/common/keyCodes'; export type OutlineItem = OutlineGroup | OutlineElement; @@ -38,7 +39,7 @@ export class OutlineNavigationLabelProvider implements IKeyboardNavigationLabelP } mightProducePrintableCharacter(event: IKeyboardEvent): boolean { - return this._keybindingService.mightProducePrintableCharacter(event); + return event.keyCode !== KeyCode.Escape && this._keybindingService.mightProducePrintableCharacter(event); } }